kitex 基于 K8s 的服务注册与发现

概览

在很久之前的文章中说过,K8s 作为云原生时代的创造者,下一代云原生的中间利器,从云原生 1.0 到 2.0,作为基石,成就无数服务畅游每一台机器。前面的文章 KiteX 入门篇 介绍了如何简单的开发一个高性能 RPC 微服务,并且我们看到其性能与吞吐还是不错的。但需要中间件 Nacos 来连接服务端与客户端。今天,我们主要从 K8s 角度来看 Kitex 如何接入云原生,甚至后面的 Istio。

实践

服务端

前面文章 KiteX 入门篇,我们介绍了如何创建一个服务端,那我们这次改造下,让其接入 K8s。

这里主要现需要去掉关于 Nacos 的逻辑,然后我们再看下面的代码:

1
server.WithServiceAddr(&net.TCPAddr{Port: 9000}),

这段代码的含义是通过 Nacos 注册时候,我们把服务注册的端口为 9000,但如果服务是以 K8s 部署的 Pod 形式,则代表的是 Pod 的端口,同时,由于 K8s 这种开源注册中心默认使用 TCP 协议,所以这里支持的是 TCP 协议。
这样简单的配置,即可让服务注册到 K8s,被 k8s-api 发现。

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
svr := note.NewServer(
new(api.NoteApi),
//基于svc进行服务注册,9000为svc的port
server.WithServiceAddr(&net.TCPAddr{Port: 9000}),
server.WithMuxTransport(),
server.WithLimit(&limit.Option{MaxConnections: 10000, MaxQPS: 5000}),

server.WithPayloadCodec(thrift.NewThriftCodecWithConfig(thrift.FastRead | thrift.FastWrite)),

//server.WithTracer(prometheus.NewServerTracer(":9092", "/kitexNoteserver")),

server.WithErrorHandler(func(err error) error {
error := errno.ConvertErr(err)
return error
}),
server.WithCodec(codec.NewDefaultCodecWithSizeLimit(1024 * 1024 * 10)),//10M

server.WithMetaHandler(transmeta.ServerTTHeaderHandler), // registry
)
err := svr.Run()
if err != nil {
klog.Fatal(err)
}
部署脚本

由于我们需要通过镜像部署服务,所以需要 dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
FROM ubuntu:16.04 as build

RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
ca-certificates \
wget && \
rm -rf /var/lib/apt/lists/*


ENV GOLANG_VERSION 1.18.1
RUN wget -nv -O - https://studygolang.com/dl/golang/go1.18.1.linux-amd64.tar.gz \
| tar -C /usr/local -xz

ENV GOPROXY=https://goproxy.cn,direct
ENV GO111MODULE=on
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH

RUN apt-get update && apt-get install -y git

WORKDIR /go/src

COPY . .
#RUN go env -w GOPROXY=https://goproxy.cn,direct
#RUN go env -w GO111MODULE=on

RUN go build -o hello-server ./server/hello
RUN chmod +x ./hello-server

RUN rm -rf cache && rm -rf kitex_gen && rm -rf README.md\
&& rm -rf build && rm -rf codec && rm -rf client \
&& rm -rf images && rm -rf idl && rm -rf go.mod && rm -rf go.sum \
&& rm -rf pkg && rm -rf script && rm -rf retry \
&& rm -rf server && rm -rf streaming && rm -rf LICENSE

CMD ["./hello-server"]

然后我们需要 K8s 的 yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-service-deployment
namespace: default
labels:
app: hello-service
spec:
replicas: 3
selector:
matchLabels:
app: hello-service
template:
metadata:
labels:
app: hello-service
spec:
nodeSelector:
hello-service: "true"
containers:
- name: node-service
image: node-service
imagePullPolicy: IfNotPresent
ports:
- name: hello01
containerPort: 9000

......

最后需要对这个服务进行创建 svc,以便进行负载均衡被其它服务所访问。

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: hello-service-svc
namespace: default
spec:
ports:
- name: hello01
port: 9000
targetPort: hello01
selector:
app: hello-service

此时,一个完整的服务端的代码以及部署脚本就完结了。

客户端

同样的,客户端我们来看看看,也是很简单,同样先需去掉 Nacos 的配置,然后我们引入利用 K8s svc 进行服务的请求:

1
client.WithHostPorts("hello-service-svc.default.svc.cluster.local:9000"),

在创建客户端的时候,客户端的 host 要写实际集群中的内网地址:hello-service-svc.default.svc.cluster.local,这样就不用再搭配第三方的服务注册中心了。

这样就可以通过该 host 进行访问服务端的服务了。。。

部署脚本

客户端的部署脚本类似服务端的,同样需要部署的构建镜像脚本、部署 deployment 脚本、部署 svc。此处客户端由于是通过容器部署,所以我们需要把其服务的 port 进行映射到主机,这样方便来进行浏览器访问服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: customer-service-svc
namespace: default
spec:
type: NodePort
ports:
- name: customer01
nodePort: 30230
port: 3000
targetPort: customer01
selector:
app: customer-service

测试

我们先通过命令进行部署:

1
kubectl create -f ...

创建完服务相关资源后,我们看看 pod:

资源 svc 情况:

我们把 port 映射到主机上,然后我们通过浏览器进行访问客户端,此处我们访问的是存在 10000 条数据入库的服务:

我们可以看到,数据大概是 9634 条总数,我们取 500 条,耗时 40ms,接下来,我们换作取 5000 条:

数据大小 624kb,发现大概耗时:159ms,还是可以的。

最后,我们看看拿全部数据大概耗时:

发现全部数据大小:1.2M,耗时 300 多毫秒,还是不错的。

特性

我们的服务为什么能如此之快呢,这里我们引入了一种高性能网络库:netpoll,以及在编解码方面,我们利用 Thrift 的 IDL 进行生成代码,同时,利用其提供的 FastRead、FastWrite 来进行快速传输。

如有想要源码的,可以关注后,后台联系博主获取哟~

结束福利

开源实战利用 k8s 作微服务的架构设计代码:

https://gitee.com/damon_one/spring-cloud-k8s

欢迎大家 star,多多指教。

关于作者

  笔名:Damon,技术爱好者,微服务架构设计,云原生、容器化技术,现从事Go相关,涉及云原生、边缘计算、AI人工智能、云产品Devops落地实践等云原生技术。拿过专利。公众号 交个朋友之猿天地 发起人。个人微信 DamonStatham,星球:《交个朋友之猿田地》,个人网站:交个朋友之猿天地 | 微服务 | 容器化 | 自动化,欢迎來撩。

欢迎关注

公号:交个朋友之猿天地

AI绘画扫我

星球

打赏
  • Copyrights © 2020-2023 交个朋友之猿天地
  • Powered By Hexo | Title - Nothing
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信