云原生架构之SpringBoot+K8s service服务注册发现方案(东西流量)

3,559 阅读3分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第3篇文章,点击查看活动详情

一 方案概述

将spring cloud应用上K8s集群,服务注册直接使用K8s service,即为服务绑定service,服务发现使用K8s service(改方案负责均衡为服务端负载均衡)。

二 SpringBoot + K8s service服务注册发现方案

2.1 方案简介

使用K8s 原生service/endpoints/coredns/etcd组建实现服务注册发现过程,服务注册使用和服务发现均使用service,在K8s环境下,借助K8s service能力实现负载均衡,更高级流量、安全等功能需要借助服务治理框架实现。

2.2 服务注册发现实现

2.2.1 服务注册过程:

spring cloud 服务配置有serivce的服务,启动后k8s集群针对调用该service,后端会返回具体的pod列表。

2.2.2 服务发现过程:

  • 在同一名称空间,直接使用service进行调用;
  • 跨名称空间使用resttemplate进行调用service;

2.3 方案特点

  • 优点:
    • 负载均衡算法在服务端实现(service 的原生负载均衡算法),后期可使用服务治理框架例如istio/linkerd进行服务治理。
  • 不足:
    • 服务直接通过k8s服务发现,经过service一层,在书主机请求通过iptables/lvs是转发一层,性能稍弱。

三 实战

3.1 服务提供者

3.1服务提供者 项目位置:github.com/redhatxl/cl…

3.2 服务消费端

3.2.1 消费者逻辑

服务注册,仅需为服务编写 service yaml 资源清单即可。 springboot-clientservice 直接使用service 发起调用,服务发现通过service后端关联的endpoints,转发至对应endpoints上。

3.2.2 服务发现

引入 spring-cloud-starter-openfeign 进行客户端http请求发起; 引入 spring-cloud-starter-loadbalancer 进行负载均衡(实际针对service发起调用不用负载均衡);

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
   <version>3.1.3</version>
</dependency>

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-loadbalancer</artifactId>
   <version>3.1.3</version>
</dependency>

3.2.3 项目目录结构

.
├── Dockerfile
├── HELP.md
├── README.md
├── deploy
│   ├── deploy.yaml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── springboot-clientservice.iml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── xuel
│   │   │           ├── controller
│   │   │           │   └── SpringBootClientServiceController.java
│   │   │           ├── feign
│   │   │           │   └── FeignService.java
│   │   │           ├── service
│   │   │           │   ├── SpringBootClientService.java
│   │   │           │   └── impl
│   │   │           │       └── SpringBootClientServiceImpl.java
│   │   │           └── springbootclientservice
│   │   │               └── SpringbootClientserviceApplication.java
│   │   └── resources
│   │       ├── application.properties
│   │       ├── static
│   │       └── templates

3.2.4 K8s部署文件

  • deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: spring
  name: springboot-clientservice
  labels:
    app: springboot-clientservice
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springboot-clientservice
  template:
    metadata:
      labels:
        app: springboot-clientservice
    spec:
      containers:
        - name: springboot-clientservice
          image: ccr.ccs.tencentyun.com/xxxxxxx-dev/springbootclientservice:img_v7
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              port: 8080
              path: /actuator/health
            periodSeconds: 10
            initialDelaySeconds: 3
            terminationGracePeriodSeconds: 10
            failureThreshold: 5
            timeoutSeconds: 10
          readinessProbe:
            httpGet:
              port: 8080
              path: /actuator/health
            initialDelaySeconds: 5
            periodSeconds: 10
            failureThreshold: 5
            timeoutSeconds: 10
  • service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: springbootclientservice
      namespace: spring
      labels:
        app: springboot-clientservice
    spec:
      ports:
        - port: 8080
          protocol: TCP
          targetPort: 8080
      type: ClusterIP
      selector:
        app: springboot-clientservice
    

3.2.5 项目源码

项目位置:github.com/redhatxl/cl…

四 测试

4.1 访问服务提供者

由于本地mac 使用kind部署,通过port-forward进行映射到宿主机。

k port-forward -n spring --address 0.0.0.0 svc/springbootinit 9999:8080

/services: 获取到对的service 列表,当前的时间,相应的 Pod 主机名称。

4.2 访问服务消费者

k port-forward -n spring --address 0.0.0.0 svc/springbootclientservice 8888:8080

/getsvc : 获取 K8s 内部列表,即请求到的 POD hostname。

在此负载均衡使用的为service的,测试访问很多次才进行轮换。

4.3 查看资源

五 其他

总结下来,服务注册通过给服务添加service,服务发现通过直接调用service发起请求。