Skip to content

Commit 8526b3a

Browse files
authored
Merge pull request #1304 from cloudwego/release-v0.9.1
chore: release v0.9.1
2 parents 92f0cb7 + ff5ca14 commit 8526b3a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2087
-335
lines changed

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ Kitex is designed to be extensible to support multiple RPC messaging protocols.
3030

3131
- **Multi-transport Protocol**
3232

33-
For service governance, Kitex supports **TTHeader** and **HTTP2**. TTHeader can be used in conjunction with Thrift and Kitex Protobuf; HTTP2 is currently mainly used with the gRPC protocol, and it will support Thrift in the future.
33+
For service governance, Kitex supports **TTHeader** and **HTTP2**. TTHeader can be used in conjunction with Thrift and Kitex Protobuf.
3434

3535
- **Multi-message Type**
3636

37-
Kitex supports **PingPong**, **One-way**, and **Bidirectional Streaming**. Among them, One-way currently only supports Thrift protocol, two-way Streaming only supports gRPC, and Kitex will support Thrift's two-way Streaming in the future.
37+
Kitex supports **PingPong**, **One-way**, and **Bidirectional Streaming**. Among them, One-way currently only supports Thrift protocol.
3838

3939
- **Service Governance**
4040

@@ -73,7 +73,10 @@ Kitex has built-in code generation tools that support generating **Thrift**, **P
7373
- **Reference**
7474

7575
- For Transport Protocol, Exception Instruction and Version Specification, please refer to [doc](https://www.cloudwego.io/docs/kitex/reference/).
76-
76+
77+
- **Best Practice**
78+
- Kitex best practices in production, such as graceful shutdown, error handling, integration testing. [More](https://www.cloudwego.io/docs/kitex/best-practice/)
79+
7780
- **FAQ**
7881

7982
- Please refer to [FAQ](https://www.cloudwego.io/docs/kitex/faq/).
@@ -92,6 +95,7 @@ We provide the [kitex-benchmark](https://github.com/cloudwego/kitex-benchmark) p
9295
- [biz-demo](https://github.com/cloudwego/biz-demo): Business demos using Kitex.
9396

9497
## Blogs
98+
- [Enhancing Performance in Microservice Architecture with Kitex](https://www.cloudwego.io/blog/2024/01/29/enhancing-performance-in-microservice-architecture-with-kitex/)
9599
- [CloudWeGo: A leading practice for building enterprise cloud native middleware!](https://www.cloudwego.io/blog/2023/06/15/cloudwego-a-leading-practice-for-building-enterprise-cloud-native-middleware/)
96100
- [Kitex: Unifying Open Source Practice for a High-Performance RPC Framework](https://www.cloudwego.io/blog/2022/09/30/kitex-unifying-open-source-practice-for-a-high-performance-rpc-framework/)
97101
- [Performance Optimization on Kitex](https://www.cloudwego.io/blog/2021/09/23/performance-optimization-on-kitex/)
@@ -100,7 +104,7 @@ We provide the [kitex-benchmark](https://github.com/cloudwego/kitex-benchmark) p
100104

101105
## Contributing
102106

103-
[Contributing](https://github.com/cloudwego/kitex/blob/develop/CONTRIBUTING.md).
107+
Contributor guide: [Contributing](https://github.com/cloudwego/kitex/blob/develop/CONTRIBUTING.md).
104108

105109
## License
106110

@@ -118,7 +122,7 @@ Kitex is distributed under the [Apache License, version 2.0](https://github.com/
118122
## Landscapes
119123

120124
<p align="center">
121-
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
125+
<img src="https://landscape.cncf.io/images/cncf-landscape-horizontal-color.svg" width="150"/>&nbsp;&nbsp;<img src="https://www.cncf.io/wp-content/uploads/2023/04/cncf-main-site-logo.svg" width="200"/>
122126
<br/><br/>
123127
CloudWeGo enriches the <a href="https://landscape.cncf.io/">CNCF CLOUD NATIVE Landscape</a>.
124128
</p>

README_cn.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ Kitex[kaɪt'eks] 字节跳动内部的 Golang 微服务 RPC 框架,具有**高
3030

3131
- **多传输协议**
3232

33-
传输协议封装消息协议进行 RPC 互通,传输协议可以额外透传元信息,用于服务治理,Kitex 支持的传输协议有 **TTHeader****HTTP2**。TTHeader 可以和 Thrift、Kitex Protobuf 结合使用;HTTP2 目前主要是结合 gRPC 协议使用,后续也会支持 Thrift
33+
传输协议封装消息协议进行 RPC 互通,传输协议可以额外透传元信息,用于服务治理,Kitex 支持的传输协议有 **TTHeader****HTTP2**。TTHeader 可以和 Thrift、Kitex Protobuf 结合使用。
3434

3535
- **多种消息类型**
3636

37-
支持 **PingPong****Oneway****双向 Streaming**。其中 Oneway 目前只对 Thrift 协议支持,双向 Streaming 只对 gRPC 支持,后续会考虑支持 Thrift 的双向 Streaming
37+
支持 **PingPong****Oneway****双向 Streaming**。其中 Oneway 目前只对 Thrift 协议支持。
3838

3939
- **服务治理**
4040

@@ -74,6 +74,9 @@ Kitex[kaɪt'eks] 字节跳动内部的 Golang 微服务 RPC 框架,具有**高
7474

7575
- 关于应用层传输协议 TTHeader、异常说明与版本管理,请参考[文档](https://www.cloudwego.io/zh/docs/kitex/reference/)
7676

77+
- **最佳实践**
78+
- Kitex 在生产环境下的最佳实践,如优雅停机、错误处理、集成测试,详见:[文档](https://www.cloudwego.io/zh/docs/kitex/best-practice/)
79+
7780
- **FAQ**
7881
- 请参考 [FAQ](https://www.cloudwego.io/zh/docs/kitex/faq/)
7982
## 框架性能
@@ -91,14 +94,15 @@ Kitex[kaɪt'eks] 字节跳动内部的 Golang 微服务 RPC 框架,具有**高
9194

9295
## 相关文章
9396

97+
- [Kitex 两周年回顾 — 能力升级、社区合作与未来展望](https://www.cloudwego.io/zh/blog/2023/11/30/kitex-%E4%B8%A4%E5%91%A8%E5%B9%B4%E5%9B%9E%E9%A1%BE-%E8%83%BD%E5%8A%9B%E5%8D%87%E7%BA%A7%E7%A4%BE%E5%8C%BA%E5%90%88%E4%BD%9C%E4%B8%8E%E6%9C%AA%E6%9D%A5%E5%B1%95%E6%9C%9B/)
9498
- [高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践](https://www.cloudwego.io/zh/blog/2022/09/20/%E9%AB%98%E6%80%A7%E8%83%BD-rpc-%E6%A1%86%E6%9E%B6-cloudwego-kitex-%E5%86%85%E5%A4%96%E7%BB%9F%E4%B8%80%E7%9A%84%E5%BC%80%E6%BA%90%E5%AE%9E%E8%B7%B5/)
9599
- [字节跳动 Go RPC 框架 Kitex 性能优化实践](https://www.cloudwego.io/zh/blog/2021/09/23/%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8-go-rpc-%E6%A1%86%E6%9E%B6-kitex-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E8%B7%B5/)
96100
- [字节跳动在 Go 网络库上的实践](https://www.cloudwego.io/zh/blog/2021/10/09/%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E5%9C%A8-go-%E7%BD%91%E7%BB%9C%E5%BA%93%E4%B8%8A%E7%9A%84%E5%AE%9E%E8%B7%B5/)
97101
- [RPC 框架 Kitex 实践入门:性能测试指南](https://www.cloudwego.io/zh/blog/2021/11/24/rpc-%E6%A1%86%E6%9E%B6-kitex-%E5%AE%9E%E8%B7%B5%E5%85%A5%E9%97%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E6%8C%87%E5%8D%97/)
98102

99103
## 贡献代码
100104

101-
[Contributing](CONTRIBUTING.md)
105+
贡献者指南:[Contributing](CONTRIBUTING.md)
102106

103107
## 开源许可
104108

@@ -109,14 +113,14 @@ Kitex 基于[Apache License 2.0](LICENSE) 许可证,其依赖的三方组件
109113
- 如何成为 member: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)
110114
- Issues: [Issues](https://github.com/cloudwego/kitex/issues)
111115
- Slack: 加入我们的 [Slack 频道](https://join.slack.com/t/cloudwego/shared_invite/zt-tmcbzewn-UjXMF3ZQsPhl7W3tEDZboA)
112-
- 飞书用户群([注册飞书](https://www.feishu.cn/)进群
116+
- 飞书用户群([注册飞书](https://www.feishu.cn/)后扫码进群
113117

114118
![LarkGroup](images/lark_group_cn.png)
115119

116120
## Landscapes
117121

118122
<p align="center">
119-
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
123+
<img src="https://landscape.cncf.io/images/cncf-landscape-horizontal-color.svg" width="150"/>&nbsp;&nbsp;<img src="https://www.cncf.io/wp-content/uploads/2023/04/cncf-main-site-logo.svg" width="200"/>
120124
<br/><br/>
121125
CloudWeGo 丰富了 <a href="https://landscape.cncf.io/">CNCF 云原生生态</a>。
122126
</p>

client/service_inline.go

Lines changed: 13 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ package client
1919
import (
2020
"context"
2121
"errors"
22-
"net"
2322
"runtime/debug"
24-
25-
"github.com/bytedance/gopkg/cloud/metainfo"
23+
"unsafe"
2624

2725
"github.com/cloudwego/kitex/client/callopt"
2826
"github.com/cloudwego/kitex/internal/client"
29-
internal_server "github.com/cloudwego/kitex/internal/server"
3027
"github.com/cloudwego/kitex/pkg/consts"
3128
"github.com/cloudwego/kitex/pkg/endpoint"
3229
"github.com/cloudwego/kitex/pkg/klog"
@@ -35,15 +32,9 @@ import (
3532
"github.com/cloudwego/kitex/pkg/utils"
3633
)
3734

38-
var localAddr net.Addr
39-
40-
func init() {
41-
localAddr = utils.NewNetAddr("tcp", "127.0.0.1")
42-
}
43-
4435
type ContextServiceInlineHandler interface {
45-
WriteMeta(cliCtx, svrCtx context.Context, req interface{}) (newSvrCtx context.Context, err error)
46-
ReadMeta(cliCtx, svrCtx context.Context, resp interface{}) (newCliCtx context.Context, err error)
36+
WriteMeta(cliCtx context.Context, req interface{}) (newCliCtx context.Context, err error)
37+
ReadMeta(cliCtx context.Context, resp interface{}) (err error)
4738
}
4839

4940
type serviceInlineClient struct {
@@ -57,15 +48,12 @@ type serviceInlineClient struct {
5748

5849
// server info
5950
serverEps endpoint.Endpoint
60-
serverOpt *internal_server.Options
6151

6252
contextServiceInlineHandler ContextServiceInlineHandler
6353
}
6454

6555
type ServerInitialInfo interface {
66-
Endpoints() endpoint.Endpoint
67-
Option() *internal_server.Options
68-
GetServiceInfos() map[string]*serviceinfo.ServiceInfo
56+
BuildServiceInlineInvokeChain() endpoint.Endpoint
6957
}
7058

7159
// NewServiceInlineClient creates a kitex.Client with the given ServiceInfo, it is from generated code.
@@ -76,10 +64,7 @@ func NewServiceInlineClient(svcInfo *serviceinfo.ServiceInfo, s ServerInitialInf
7664
kc := &serviceInlineClient{}
7765
kc.svcInfo = svcInfo
7866
kc.opt = client.NewOptions(opts)
79-
kc.serverEps = s.Endpoints()
80-
kc.serverOpt = s.Option()
81-
kc.serverOpt.RemoteOpt.TargetSvcInfo = svcInfo
82-
kc.serverOpt.RemoteOpt.SvcSearchMap = s.GetServiceInfos()
67+
kc.serverEps = s.BuildServiceInlineInvokeChain()
8368
if err := kc.init(); err != nil {
8469
_ = kc.Close()
8570
return nil, err
@@ -176,88 +161,25 @@ func (kc *serviceInlineClient) buildInvokeChain() error {
176161
return nil
177162
}
178163

179-
func (kc *serviceInlineClient) constructServerCtxWithMetadata(cliCtx context.Context) (serverCtx context.Context) {
180-
serverCtx = context.Background()
181-
// metainfo
182-
// forward transmission
183-
kvs := make(map[string]string, 16)
184-
metainfo.SaveMetaInfoToMap(cliCtx, kvs)
185-
if len(kvs) > 0 {
186-
serverCtx = metainfo.SetMetaInfoFromMap(serverCtx, kvs)
187-
}
188-
serverCtx = metainfo.TransferForward(serverCtx)
189-
// reverse transmission, backward mark
190-
serverCtx = metainfo.WithBackwardValuesToSend(serverCtx)
191-
return serverCtx
192-
}
193-
194-
func (kc *serviceInlineClient) constructServerRPCInfo(svrCtx, cliCtx context.Context) (newServerCtx context.Context, svrRPCInfo rpcinfo.RPCInfo) {
195-
rpcStats := rpcinfo.AsMutableRPCStats(rpcinfo.NewRPCStats())
196-
if kc.serverOpt.StatsLevel != nil {
197-
rpcStats.SetLevel(*kc.serverOpt.StatsLevel)
198-
}
199-
// Export read-only views to external users and keep a mapping for internal users.
200-
ri := rpcinfo.NewRPCInfo(
201-
rpcinfo.EmptyEndpointInfo(),
202-
rpcinfo.FromBasicInfo(kc.serverOpt.Svr),
203-
rpcinfo.NewServerInvocation(),
204-
rpcinfo.AsMutableRPCConfig(kc.serverOpt.Configs).Clone().ImmutableView(),
205-
rpcStats.ImmutableView(),
206-
)
207-
rpcinfo.AsMutableEndpointInfo(ri.From()).SetAddress(localAddr)
208-
svrCtx = rpcinfo.NewCtxWithRPCInfo(svrCtx, ri)
209-
210-
cliRpcInfo := rpcinfo.GetRPCInfo(cliCtx)
211-
// handle common rpcinfo
212-
method := cliRpcInfo.To().Method()
213-
if ink, ok := ri.Invocation().(rpcinfo.InvocationSetter); ok {
214-
ink.SetMethodName(method)
215-
ink.SetServiceName(kc.svcInfo.ServiceName)
216-
}
217-
rpcinfo.AsMutableEndpointInfo(ri.To()).SetMethod(method)
218-
svrCtx = context.WithValue(svrCtx, consts.CtxKeyMethod, method)
219-
return svrCtx, ri
220-
}
221-
222164
func (kc *serviceInlineClient) invokeHandleEndpoint() (endpoint.Endpoint, error) {
223-
svrTraceCtl := kc.serverOpt.TracerCtl
224-
if svrTraceCtl == nil {
225-
svrTraceCtl = &rpcinfo.TraceController{}
226-
}
227-
228165
return func(ctx context.Context, req, resp interface{}) (err error) {
229-
serverCtx := kc.constructServerCtxWithMetadata(ctx)
230-
defer func() {
231-
// backward key
232-
kvs := metainfo.AllBackwardValuesToSend(serverCtx)
233-
if len(kvs) > 0 {
234-
metainfo.SetBackwardValuesFromMap(ctx, kvs)
235-
}
236-
}()
237-
serverCtx, svrRPCInfo := kc.constructServerRPCInfo(serverCtx, ctx)
238-
defer func() {
239-
rpcinfo.PutRPCInfo(svrRPCInfo)
240-
}()
241-
242-
// server trace
243-
serverCtx = svrTraceCtl.DoStart(serverCtx, svrRPCInfo)
244-
166+
cliRpcInfo := rpcinfo.GetRPCInfo(ctx)
167+
if v, ok := cliRpcInfo.Invocation().(rpcinfo.InvocationSetter); ok {
168+
v.SetExtra(consts.SERVICE_INLINE_SERVICE_NAME, kc.svcInfo.ServiceName)
169+
}
170+
ctx = context.WithValue(ctx, consts.SERVICE_INLINE_RPCINFO_KEY, unsafe.Pointer(&cliRpcInfo))
245171
if kc.contextServiceInlineHandler != nil {
246-
serverCtx, err = kc.contextServiceInlineHandler.WriteMeta(ctx, serverCtx, req)
172+
ctx, err = kc.contextServiceInlineHandler.WriteMeta(ctx, req)
247173
if err != nil {
248174
return err
249175
}
250176
}
251177

252178
// server logic
253-
err = kc.serverEps(serverCtx, req, resp)
254-
// finish server trace
255-
// contextServiceInlineHandler may convert nil err to non nil err, so handle trace here
256-
svrTraceCtl.DoFinish(serverCtx, svrRPCInfo, err)
179+
err = kc.serverEps(ctx, req, resp)
257180

258181
if kc.contextServiceInlineHandler != nil {
259-
var err1 error
260-
ctx, err1 = kc.contextServiceInlineHandler.ReadMeta(ctx, serverCtx, resp)
182+
err1 := kc.contextServiceInlineHandler.ReadMeta(ctx, resp)
261183
if err1 != nil {
262184
return err1
263185
}

client/service_inline_test.go

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,18 @@ import (
3030
"github.com/cloudwego/kitex/client/callopt"
3131
"github.com/cloudwego/kitex/internal/client"
3232
"github.com/cloudwego/kitex/internal/mocks"
33-
internal_server "github.com/cloudwego/kitex/internal/server"
3433
"github.com/cloudwego/kitex/internal/test"
35-
"github.com/cloudwego/kitex/pkg/consts"
3634
"github.com/cloudwego/kitex/pkg/endpoint"
3735
"github.com/cloudwego/kitex/pkg/kerrors"
3836
"github.com/cloudwego/kitex/pkg/rpcinfo"
3937
"github.com/cloudwego/kitex/pkg/rpcinfo/remoteinfo"
40-
"github.com/cloudwego/kitex/pkg/serviceinfo"
4138
)
4239

4340
type serverInitialInfoImpl struct {
4441
EndpointsFunc func(ctx context.Context, req, resp interface{}) (err error)
4542
}
4643

47-
func (s serverInitialInfoImpl) Endpoints() endpoint.Endpoint {
44+
func (s serverInitialInfoImpl) BuildServiceInlineInvokeChain() endpoint.Endpoint {
4845
if s.EndpointsFunc != nil {
4946
return s.EndpointsFunc
5047
}
@@ -53,14 +50,6 @@ func (s serverInitialInfoImpl) Endpoints() endpoint.Endpoint {
5350
}
5451
}
5552

56-
func (s serverInitialInfoImpl) Option() *internal_server.Options {
57-
return internal_server.NewOptions(nil)
58-
}
59-
60-
func (s serverInitialInfoImpl) GetServiceInfos() map[string]*serviceinfo.ServiceInfo {
61-
return nil
62-
}
63-
6453
func newMockServerInitialInfo() ServerInitialInfo {
6554
return &serverInitialInfoImpl{}
6655
}
@@ -347,28 +336,3 @@ func TestServiceInlineClientFinalizer(t *testing.T) {
347336
t.Logf("After second GC, allocation: %f Mb, Number of allocation: %d\n", secondGCHeapAlloc, secondGCHeapObjects)
348337
test.Assert(t, secondGCHeapAlloc < firstGCHeapAlloc/2 && secondGCHeapObjects < firstGCHeapObjects/2)
349338
}
350-
351-
func TestServiceInlineMethodKeyCall(t *testing.T) {
352-
ctrl := gomock.NewController(t)
353-
defer ctrl.Finish()
354-
mtd := mocks.MockMethod
355-
opts := []Option{
356-
WithTransHandlerFactory(newMockCliTransHandlerFactory(ctrl)),
357-
WithResolver(resolver404(ctrl)),
358-
WithDialer(newDialer(ctrl)),
359-
WithDestService("destService"),
360-
}
361-
svcInfo := mocks.ServiceInfo()
362-
s := serverInitialInfoImpl{}
363-
s.EndpointsFunc = func(ctx context.Context, req, resp interface{}) (err error) {
364-
test.Assert(t, ctx.Value(consts.CtxKeyMethod) == mtd)
365-
return nil
366-
}
367-
cli, err := NewServiceInlineClient(svcInfo, s, opts...)
368-
test.Assert(t, err == nil)
369-
ctx := context.Background()
370-
req := new(MockTStruct)
371-
res := new(MockTStruct)
372-
err = cli.Call(ctx, mtd, req, res)
373-
test.Assert(t, err == nil, err)
374-
}

client/stream.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io"
2222
"sync/atomic"
2323

24+
"github.com/cloudwego/kitex/pkg/kerrors"
2425
"github.com/cloudwego/kitex/pkg/remote/trans/nphttp2/metadata"
2526
"github.com/cloudwego/kitex/pkg/serviceinfo"
2627

@@ -164,6 +165,8 @@ func (s *stream) Context() context.Context {
164165
func (s *stream) RecvMsg(m interface{}) (err error) {
165166
err = s.recvEndpoint(s.stream, m)
166167
if err == nil {
168+
// BizStatusErr is returned by the server handle, meaning the stream is ended;
169+
// And it should be returned to the calling business code for error handling
167170
err = s.ri.Invocation().BizStatusErr()
168171
}
169172
if err != nil || s.streamingMode == serviceinfo.StreamingClient {
@@ -193,10 +196,23 @@ func (s *stream) DoFinish(err error) {
193196
// already called
194197
return
195198
}
196-
if err == io.EOF {
199+
if !isRPCError(err) {
200+
// only rpc errors are reported
197201
err = nil
198202
}
199203
ctx := s.Context()
200204
ri := rpcinfo.GetRPCInfo(ctx)
201205
s.kc.opt.TracerCtl.DoFinish(ctx, ri, err)
202206
}
207+
208+
func isRPCError(err error) bool {
209+
if err == nil {
210+
return false
211+
}
212+
if err == io.EOF {
213+
return false
214+
}
215+
_, isBizStatusError := err.(kerrors.BizStatusErrorIface)
216+
// if a tracer needs to get the BizStatusError, it should read from rpcinfo.invocation.bizStatusErr
217+
return !isBizStatusError
218+
}

0 commit comments

Comments
 (0)