前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >KiteX 基于 K8s 的服务注册与发现

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

作者头像
程序猿Damon
发布2022-12-05 11:06:07
7660
发布2022-12-05 11:06:07
举报

概览

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

实践

服务端

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

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

代码语言:javascript
复制
server.WithServiceAddr(&net.TCPAddr{Port: 9000}),

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

完整代码如下:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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,以便进行负载均衡被其它服务所访问。

代码语言:javascript
复制
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 进行服务的请求:

代码语言:javascript
复制
client.WithHostPorts("hello-service-svc.default.svc.cluster.local:9000"),

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

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

部署脚本

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

代码语言:javascript
复制
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

测试

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

代码语言:javascript
复制
kubectl create -f ...

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

资源 svc 情况:

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

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

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

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

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

特性

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 交个朋友之猿天地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概览
  • 实践
    • 服务端
      • 客户端
        • 测试
        • 特性
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档