Akemi

将SpringCloud项目迁移至k8s

2024/06/01

整体流程
1、把Springcloud开发的java代码做到镜像里:可以基于dockerfile文件做镜像
2、把镜像传到镜像仓库
3、创建pod,用deployment或statefulset创建
4、创建四层代理Service
5、搭建七层代理Ingress-nginx-controller
6、数据持久化:ceph、nfs、云存储
7、搭建监控系统和日志收集系统:prometheus+alertmagaer+grafana、EFK+logstash+kafka
8、链路监控:pinpoint、zipkin、skywalking

微服务架构

微服务是一种软件开发架构模式,用于构建应用程序。它是一种将单个应用程序拆分为一组小型、独立的服务的方法。每个微服务都是一个独立的、可独立部署和扩展的单元,通过轻量级通信机制相互交互。

微服务架构的核心思想是将应用程序拆分为一组小型服务,每个服务专注于特定的业务功能。每个微服务都有自己的数据库和业务逻辑,并且可以使用不同的编程语言和技术栈进行开发。这使得团队可以独立地开发、测试、部署和扩展每个微服务,而不会对其他服务产生影响。

特点:

  • 独立开发和部署:每个微服务可以由不同的团队开发和部署,可以快速迭代和发布新功能。
  • 弹性和可伸缩性:每个微服务可以独立进行扩展,以满足不同的负载需求。
  • 技术多样性:不同的微服务可以使用不同的编程语言和技术栈,以适应特定的业务需求。
  • 容错性和可靠性:如果一个微服务发生故障,其他微服务仍然可以继续工作,降低了系统的整体风险。
  • 可维护性:由于每个微服务都较小且专注于特定功能,因此更容易理解、调试和修改。

特性:

  1. 服务拆分与自治性:
    微服务将应用程序拆分为一组小型服务,每个服务专注于特定的业务功能。每个微服务都是一个独立的、自治的单元,可以独立开发、部署和扩展。这种拆分和自治性使得团队可以独立管理和演化每个微服务。
  2. 独立部署和可扩展性:
    微服务可以独立部署和扩展。由于每个微服务是一个独立的组件,可以根据需要对其进行扩展,而不会影响其他服务。这种独立部署和可扩展性使得应用程序更具弹性和可伸缩性。
  3. 轻量级通信机制:
    微服务之间通过轻量级的通信机制进行交互,常见的包括基于HTTP的RESTful API、消息队列或RPC(远程过程调用)。这种通信机制使得微服务之间可以进行解耦,实现松耦合的架构。
  4. 多语言和技术栈支持:
    微服务架构支持使用不同的编程语言和技术栈来开发不同的微服务。团队可以选择最适合自己的技术栈,以满足特定的业务需求。这种灵活性使得团队能够在不同的微服务中使用最佳工具和技术。
  5. 独立数据存储:
    每个微服务可以拥有自己的数据存储,可以选择适合自己的数据库或存储技术。这样可以使每个微服务能够更好地管理自己的数据,避免数据耦合和共享数据的复杂性。
  6. 容错性和弹性设计:
    微服务架构具有容错性,即当一个微服务发生故障时,不会影响整个应用程序的运行。其他微服务仍然可以继续工作,从而提高了系统的可靠性。此外,微服务的独立部署和隔离性也有助于减少故障的影响范围。
  7. 持续交付和快速迭代 CI/CD:
    微服务架构支持持续交付和快速迭代的开发流程。由于每个微服务都是独立的,团队可以独立开发、测试和部署每个微服务。这种灵活性使得团队能够更快地发布新功能和修复问题。

常见微服务框架

  1. Spring Cloud: Spring Cloud是基于Java的微服务框架,构建在Spring Framework之上。它提供了一系列工具和库,用于快速开发和部署微服务应用程序。Spring Cloud包括服务注册与发现、负载均衡、断路器、配置管理等功能,如Eureka、Ribbon、Hystrix、Config等。
  2. Netflix OSS: Netflix开源了一套用于构建可扩展、高性能微服务的工具集,被广泛应用于微服务架构中。这些工具包括服务注册与发现(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、网关(Zuul)、分布式跟踪(Zipkin)等。
  3. Kubernetes: Kubernetes是一个容器编排平台,也可以用于部署和管理微服务。它提供了强大的容器编排、服务发现、自动伸缩和负载均衡等功能。Kubernetes能够管理和调度微服务的容器实例,并提供故障恢复和自动扩展能力。
  4. Service Mesh: Service Mesh是一种用于管理微服务通信的新型架构模式。它通过在微服务之间插入一个专用的代理层,提供了诸如服务发现、负载均衡、安全认证、故障恢复等功能。常见的Service Mesh实现包括Envoy、Linkerd和Istio。

springcloud组件简单介绍

Eureka服务发现

Eureka 是 Netflix 开源的一个服务注册和发现组件,它是 Spring Cloud 中非常常用的组件之一,用于实现微服务架构中的服务注册中心。

  1. 服务注册中心:Eureka 由一个或多个服务注册中心组成,每个注册中心负责管理和维护服务实例的注册信息。服务提供者将自己的信息注册到注册中心,而服务消费者则从注册中心获取服务提供者的信息。注册中心使用心跳机制来监测服务实例的可用性,并在服务实例不可用时进行剔除。
  2. 服务实例:在 Eureka 中,服务提供者被称为服务实例。每个服务实例都会向注册中心注册自己的信息,包括服务名称、IP 地址、端口号等。服务实例会周期性地发送心跳请求,以告知注册中心自己的健康状态。
  3. 服务发现:服务消费者通过向注册中心发送查询请求,从注册中心获取服务实例的信息。Eureka 提供了简单易用的 REST API,使得服务消费者可以通过 HTTP 协议与注册中心进行通信,从而获取服务实例的地址和相关元数据信息。
  4. 客户端库:Eureka 提供了客户端库,使得服务提供者和消费者可以方便地与注册中心进行交互。Spring Cloud 通过集成 Eureka 客户端库,提供了自动化的服务注册和发现的能力。

特点:

  • 高可用性:Eureka 的注册中心可以通过运行多个实例来实现高可用性。每个实例通过相互注册来进行信息同步,以确保注册中心的可用性和数据的一致性。
  • 自我保护机制:Eureka 引入了自我保护机制,用于应对网络分区故障或注册中心出现故障时的情况。当注册中心在一定时间内未接收到心跳时,会进入自我保护模式,不会剔除正常的服务实例。
  • 可扩展性:Eureka 支持水平扩展,可以根据负载情况和需求增加或减少注册中心的实例数,以提高系统的扩展性和容量。

Ribbon负载均衡

Ribbon 是 Netflix 开源的一个客户端负载均衡器,它是 Spring Cloud 中常用的组件之一,用于在服务消费者端实现负载均衡。

Ribbon实现的是客户端负载均衡,它可以在客户端经过一系列算法来均衡调用服务。Ribbon 工作时分两步:
第一步:从Eureka Server中获取服务注册信息列表,它优先选择在同一个 Zone 且负载较少的 Server。
第二步:根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址,其中Ribbon提供了多种策略,例如轮询、随机等。

相比之下
Nginx是服务器端负载均衡,所有请求统一交给nginx,由nginx实现负载均衡请求转发,属于服务器端负载均衡。

Zuul网关

Zuul是SpringCloud中的网关。也是会在Eureka注册中心中进行服务的注册和发现。

网关是微服务架构中的入口点,它扮演着转发请求、认证授权、负载均衡、缓存等功能的角色。Zuul 提供了以下主要功能:

  1. 路由转发:Zuul 可以根据请求的路径和规则将请求转发到对应的后端服务实例。它支持动态路由配置,可以根据实际需要进行灵活的路由配置和管理。
  2. 过滤器:Zuul 提供了过滤器机制,可以在请求的不同阶段进行预处理或后处理。通过定义和配置不同类型的过滤器,可以实现请求鉴权、请求日志记录、请求重写等功能。
  3. 负载均衡:Zuul 集成了 Ribbon 负载均衡器,可以将请求分发到多个后端服务实例,以实现负载均衡和高可用性。
  4. 容错机制:Zuul 支持容错和熔断机制,当后端服务实例不可用或发生故障时,可以自动切换到其他可用的实例,以提高系统的可靠性和稳定性。
  5. 缓存支持:Zuul 可以对请求的响应进行缓存,以减轻后端服务的负载并提高响应速度。它支持基于时间或条件的缓存策略,并可以根据需求进行灵活的缓存配置。

Hystrix熔断器

在微服务架构中,在高并发情况下,如果请求数量达到一定极限(可以自己设置阈值),超出了设置的阈值,Hystrix会自动开启服务保护功能,然后通过服务降级的方式返回一个友好的提示给客户端。假设当10个请求中,有10%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到10s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

服务降级
在高并发的场景下,当服务器的压力剧增时,根据当前业务以及流量的情况,对一些服务和页面进行策略控制,对这些请求做简单的处理或者不处理,来释放服务器资源用以保证核心业务不受影响,确保业务可以正常对外提供服务

springcloud gateway API网关

Spring Cloud已经放弃Zuul了。现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是基于过滤器的,是阻塞IO,不支持长连接,spring官网上也已经没有zuul的组件了。

  1. 路由转发:Spring Cloud Gateway 可以根据请求的路径和规则将请求转发到对应的后端服务。它支持动态路由配置,可以根据实际需要进行灵活的路由配置和管理。
  2. 过滤器:Gateway 提供了强大的过滤器机制,可以在请求的不同阶段进行预处理或后处理。通过定义和配置不同类型的过滤器,可以实现请求鉴权、请求日志记录、请求转换等功能。
  3. 负载均衡:Spring Cloud Gateway 集成了负载均衡器,可以将请求分发到多个后端服务实例,以实现负载均衡和高可用性。
  4. 断路器:Gateway 支持断路器模式,当后端服务实例不可用或发生故障时,可以通过断路器机制进行故障快速响应,从而提高系统的稳定性。
  5. 集成性:Spring Cloud Gateway 可以方便地与其他 Spring Cloud 组件进行集成,如服务注册与发现组件(如 Eureka、Consul)、配置中心(如 Spring Cloud Config)等,以构建完整的微服务架构。

与zuul的区别:

  1. 底层技术栈:Spring Cloud Gateway 基于 Spring 5、Spring Boot 2 和 Project Reactor,使用响应式编程模型。而 Zuul 基于 Servlet 技术栈,使用阻塞式 I/O 模型。
  2. 性能和可扩展性:由于使用了响应式编程模型和异步非阻塞的方式处理请求,Spring Cloud Gateway 在性能和可扩展性方面更加出色。相比之下,Zuul 在处理高并发请求时可能面临阻塞线程池资源耗尽的问题。
  3. 路由和过滤器:两者都提供了路由转发和过滤器的功能,但实现方式有所不同。Spring Cloud Gateway 使用路由谓词和过滤器链的概念,可以更细粒度地配置路由规则和过滤器。而 Zuul 使用简单的路径匹配和过滤器类型来进行路由和过滤器配置。
  4. 动态路由:Spring Cloud Gateway 提供了动态路由的支持,可以通过配置中心(如 Spring Cloud Config)动态更新路由规则。Zuul 目前在动态路由方面的支持相对较弱。
  5. 生态系统集成:Zuul 是 Netflix 发布的第一代 API 网关,具有丰富的功能和生态系统(如 Ribbon、Eureka)。Spring Cloud Gateway 是 Spring Cloud 生态系统中较新的组件,与 Spring Boot、Spring Cloud 集成更加紧密。

SpringCloud Config配置中心

Spring Cloud Config 是 Spring Cloud 提供的一个分布式配置管理工具,用于集中管理和提供应用程序的配置信息。它允许将配置文件存储在配置服务器中,并通过客户端将配置动态地分发给不同的服务实例

  1. 配置服务器(Config Server):配置服务器是一个独立的组件,用于存储和管理配置文件。它可以从本地文件系统、Git 仓库或其他外部存储中获取配置文件,并提供 REST 接口供客户端访问。
  2. 配置文件:配置文件是应用程序的配置信息,如数据库连接、服务端口、日志级别等。Spring Cloud Config 使用约定的文件命名规则(例如 propertiesapplication.yml)来标识不同的配置文件。
  3. 配置客户端(Config Client):配置客户端是服务实例或应用程序,通过向配置服务器发起请求获取自身所需的配置信息。它与配置服务器进行交互,并将配置信息加载到应用程序中。
  4. 配置刷新(Refresh):配置刷新是指在运行时更新配置信息,而无需重启应用程序。通过发送请求到配置服务器的 /actuator/refresh 端点,可以触发配置的刷新,使客户端重新加载最新的配置。

迁移

安装mysql

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
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install mysql-server -y
# 权限
chown mysql:mysql -R /var/lib/mysql
# 初始化
mysqld --initialize
# 启动
systemctl enable mysqld --now

# 设置初始密码
mysqladmin -u root password "123456"

# 登录
mysql -uroot -p123456

# 创建数据库tb_order、tb_product、tb_stock
create database tb_product;
create database tb_stock;
create database tb_order;

# 导入数据
use tb_order
source /root/order.sql

use tb_stock
source /root/stock.sql

use tb_product
source /root/product.sql

# 授权
grant all on *.* to 'root'@'%' identified by '123456';
flush privileges;

安装openjdk和maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
yum install java-1.8.0-openjdk  maven-3.0.5* -y

unzip microservic-test.zip
cd microservic-test

cat /root/springcloud-k8s/microservic-test/stock-service/stock-service-biz/src/main/resources/application-fat.yml
jdbc:mysql://192.168.10.121:3306/tb_stock?characterEncoding=utf-8

# 修改数据库链接地址
vim /root/springcloud-k8s/microservic-test/stock-service/stock-service-biz/src/main/resources/application-fat.yml

vim /root/springcloud-k8s/microservic-test/product-service/product-service-biz/src/main/resources/application-fat.yml

vim /root/springcloud-k8s/microservic-test/order-service/order-service-biz/src/main/resources/application-fat.yml

# 编译
mvn clean package -D maven.test.skip=true

部署eureka服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
1.登录harbor,并且拉取、生成harbor的secret
docker login 192.168.10.130
kubectl create ns ms && kubectl create secret docker-registry \
registry-pull-secret --docker-server=192.168.10.130 --docker-username=admin \
--docker-password=Harbor12345 -n ms

2.在harbor上创建一个新project - microservice

3.构建镜像
docker load -i jave-8.tar.gz
cd /root/springcloud-k8s/microservic-test/eureka-service/
# ls
# Dockerfile pom.xml src target
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/eureka-service.jar ./
EXPOSE 8888
CMD java -jar -Deureka.instance.hostname=${MY_POD_NAME}.eureka.ms /eureka-service.jar

docker build -t 192.168.10.130/microservice/eureka:v1 . # 构建
docker push 192.168.10.130/microservice/eureka:v1 # 推送

#
4.部署pod
cat eureka.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: eureka
namespace: ms
spec:
ingressClassName: nginx
rules:
- host: eureka.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: eureka
port:
number: 8888
---
apiVersion: v1
kind: Service
metadata:
name: eureka
namespace: ms
spec:
clusterIP: None
ports:
- port: 8888
name: eureka
selector:
project: ms
app: eureka
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka
namespace: ms
spec:
replicas: 3
selector:
matchLabels:
project: ms
app: eureka
serviceName: "eureka"
template:
metadata:
labels:
project: ms
app: eureka
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: eureka
image: 192.168.10.130/microservice/eureka:v1
ports:
- protocol: TCP
containerPort: 8888
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8888
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8888
initialDelaySeconds: 60
periodSeconds: 10
kubectl apply -f eureka.yaml

kubectl get pods -n ms
#NAME READY STATUS RESTARTS AGE
#eureka-0 1/1 Running 0 48m
#eureka-1 1/1 Running 0 47m
#eureka-2 1/1 Running 1 (46m ago) 46m

kubectl get pods -n ingress-nginx -owide
# ingress-nginx-controller-58b5f9494-ph6bp 192.168.10.133 ws-k8s-node3 <none> <none>

kubectl get ingress -n ms
#NAME CLASS HOSTS ADDRESS PORTS AGE
#eureka nginx eureka.ctnrs.com 192.168.10.133 80 3m20s

5.测试

部署gateway服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
1.构建镜像
cd /root/springcloud-k8s/microservic-test/gateway-service
cat Dockerfile
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/gateway-service.jar ./
EXPOSE 9999
CMD java -jar /gateway-service.jar

docker build -t 192.168.10.130/microservice/gateway:v1 .
docker push 192.168.10.130/microservice/gateway:v1

2.部署yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gateway
namespace: ms
spec:
ingressClassName: nginx
rules:
- host: gateway.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gateway
port:
number: 9999
---
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: ms
spec:
ports:
- port: 9999
name: gateway
selector:
project: ms
app: gateway
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: gateway
template:
metadata:
labels:
project: ms
app: gateway
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: gateway
image: 192.168.10.130/microservice/gateway:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 9999
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 9999
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 9999
initialDelaySeconds: 60
periodSeconds: 10
kubectl apply -f gateway.yaml
kubectl get pods -n ms | grep gate
# gateway-546878bb75-8xkxt 1/1 Running 0 99s
kubectl get ingress -n ms
#NAME CLASS HOSTS ADDRESS PORTS AGE
#eureka nginx eureka.ctnrs.com 192.168.10.133 80 64m
#gateway nginx gateway.ctnrs.com 192.168.10.133 80 115s

3.测试

部署portal前端服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
1.构建镜像
cd /root/springcloud-k8s/microservic-test/portal-service
cat Dockerfile
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/portal-service.jar ./
EXPOSE 8080
CMD java -jar /portal-service.jar

docker build -t 192.168.10.130/microservice/portal:v1 .
docker push 192.168.10.130/microservice/portal:v1

2.部署yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portal
namespace: ms
spec:
ingressClassName: nginx
rules:
- host: portal.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: portal
port:
number: 8080
---
apiVersion: v1
kind: Service
metadata:
name: portal
namespace: ms
spec:
ports:
- port: 8080
name: portal
selector:
project: ms
app: portal
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: portal
template:
metadata:
labels:
project: ms
app: portal
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: portal
image: 192.168.10.130/microservice/portal:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources:
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10

kubectl apply -f portal.yaml
kubectl get pod -n ms | grep portal
#portal-6dffbf9777-lrtll 1/1 Running 0 2m36s
kubectl get ingress -n ms
#NAME CLASS HOSTS ADDRESS PORTS AGE
#eureka nginx eureka.ctnrs.com 192.168.10.133 80 87m
#gateway nginx gateway.ctnrs.com 192.168.10.133 80 25m
#portal nginx portal.ctnrs.com 192.168.10.133 80 2m52s

3.测试

部署order订单服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
1.构建镜像
cd /root/springcloud-k8s/microservic-test/order-service/order-service-biz
cat Dockerfile
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/order-service-biz.jar ./
EXPOSE 8020
CMD java -jar /order-service-biz.jar

docker build -t 192.168.10.130/microservice/order:v1 .
docker push 192.168.10.130/microservice/order:v1

2.部署yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: order
template:
metadata:
labels:
project: ms
app: order
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: order
image: 192.168.10.130/microservice/order:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8020
readinessProbe:
tcpSocket:
port: 8020
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8020
initialDelaySeconds: 60
periodSeconds: 10
kubectl apply -f order.yaml

kubectl get pods -n ms | grep order
#order-7cf6564c7c-qxh58 1/1 Running 0 86s

order不需要配置七层代理,因为不需要显示到前端网页

部署product产品服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
构建镜像:
cat Dockerfile
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/product-service-biz.jar ./
EXPOSE 8010
CMD java -jar /product-service-biz.jar

docker build -t 192.168.10.130/microservice/product:v1 .
docker push 192.168.10.130/microservice/product:v1

创建yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: product
namespace: ms
spec:
replicas: 3
selector:
matchLabels:
project: ms
app: product
template:
metadata:
labels:
project: ms
app: product
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: product
image: 192.168.10.130/microservice/product:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8010
resources:
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8010
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8010
initialDelaySeconds: 60
periodSeconds: 10
kubectl apply -f product.yaml

kubectl get pods -n ms | grep pro
#product-c56f784d7-bpwsh 1/1 Running 0 85s
#product-c56f784d7-cslvp 1/1 Running 0 85s
#product-c56f784d7-pfpnt 1/1 Running 0 85s

部署stock库存服务

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
构建镜像:
cat Dockerfile
FROM java:8-jdk-alpine
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/stock-service-biz.jar ./
EXPOSE 8030
CMD java -jar /stock-service-biz.jar

docker build --no-cache -t 192.168.10.130/microservice/stock:v1 .
docker push 192.168.10.130/microservice/stock:v1

部署yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: stock
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: stock
template:
metadata:
labels:
project: ms
app: stock
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: stock
image: 192.168.10.130/microservice/stock:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8030
resources:
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8030
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8030
initialDelaySeconds: 60
periodSeconds: 10
kubectl apply -f stock.yaml

全链路监控————pinpoint

在分布式微服务架构中,系统为了接收并处理一个前端用户请求,需要让多个微服务应用协同工作,其中的每一个微服务应用都可以用不同的编程语言构建,由不同的团队开发,并可以通过多个对等的应用实例实现水平扩展,甚至分布在横跨多个数据中心的数千台服务器上。单个用户请求会引发不同应用之间产生一串顺序性的调用关系,如果要对这些调用关系进行监控,了解每个应用如何调用,这就产生了全链路监控。

  1. 请求链路追踪,故障快速定位:可以通过调用链结合业务日志快速定位错误信息。
  2. 可视化: 各个阶段耗时,进行性能分析。
  3. 依赖优化:各个调用环节的可用性、梳理服务依赖关系以及优化。
  4. 数据分析,优化链路:可以得到用户的行为路径,汇总分析应用在很多业务场景。

常见的全链路监控工具

zipkin

zipkin是一个分布式的追踪系统,它能够帮助你收集服务架构中解决问题需要的时间数据,功能包括收集和查找这些数据。如果日志文件中有跟踪ID,可以直接跳转到它。否则,可以根据服务、操作名称、标记和持续时间等属性进行查询。例如在服务中花费的时间百分比,以及哪些环节操作失败。特点是轻量,使用部署简单。

zipkin还提供了一个UI界面,它能够显示通过每个应用程序的跟踪请求数。这有助于识别聚合行为,包括错误路径或对不推荐使用的服务的调用。

skywalking

skywalking是本土开源的调用链追踪系统,包括监控、跟踪、诊断功能,目前已加入Apache孵化器,专门为微服务、云本地和基于容器(Docker、Kubernetes、Mesos)架构设计。

主要功能如下:
1)服务、服务实例、端点指标数据分析
2)根本原因分析,在运行时评测代码
3)服务拓扑图分析
4)服务、服务实例和端点依赖性分析
5)检测到慢速服务和终结点
6)性能优化
7)分布式跟踪和上下文传播
8)数据库访问度量。检测慢速数据库访问语句(包括SQL语句)。
9)报警
10)浏览器性能监视

pinpoint

pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。Pinpoint提供了一个解决方案,可以帮助分析系统的整体结构,以及通过跟踪分布式应用程序中的事务来分析其中的组件是如何相互连接的。

功能如下:
1)一目了然地了解应用程序拓扑
2)实时监视应用程序
3)获得每个事务的代码级可见性
4)安装APM代理程序,无需更改一行代码
5)对性能的影响最小(资源使用量增加约3%)

pinpoint全链路监控安装部署

使用Pinpoint-docker安装,下载地址https://github.com/pinpoint-apm/pinpoint-docker

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
环境
8C4G
centos7.9
192.168.10.150/24
pinpoint版本2.0.1

# 环境初始化
hostnamectl set-hostname pinpoint && bash
nmcli con modify ens18 ipv4.method manual ipv4.dns 192.168.1.1 ipv4.gateway 192.168.10.1 ipv4.addresses 192.168.10.150/24
nmcli con up ens18
# 安全
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl disable firewalld --now
# docker源
yum install yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum -y install wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack ntpdate yum-utils device-mapper-persistent-data lvm2 telnet
# 时钟同步
yum -y install chrony
sed -i 's/^server/#server/g' /etc/chrony.conf
sed -i '1s/^/server cn.pool.ntp.org iburst\n/' /etc/chrony.conf
systemctl restart chronyd
# 修改内核参数
modprobe br_netfilter
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system # 加载所有内核
# 使其可以进行路由转发

# 安装并配置docker,只要指定docker版本安装
yum install -y docker-ce-19.03.7-3.el7
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://docker.m.daocloud.io",
"https://ghcr.io",
"https://mirror.baidubce.com",
"https://docker.nju.edu.cn"]
}
EOF
systemctl restart docker
systemctl enable docker --now

# 配置k8s源
cat > /etc/yum.repos.d/k8s.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
EOF
# 安装docker-compose
curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# 拉取需要安装pinpoint的镜像
docker-compose pull
修改docker-compose.yaml,verison改为2.2
# 启动服务
docker-compose up -d

# 访问8079端口

源代码添加Pinpoint配置,指定pinpoint服务端
添加完成后重新maven编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
yum -y install maven
mvn clean package -D maven.test.skip=true

# 重新制作镜像,上传到harbor
docker build -t 192.168.10.130/microservice/product:v2 .
docker push 192.168.10.130/microservice/product:v2
docker build -t 192.168.10.130/microservice/order:v2 .
docker push 192.168.10.130/microservice/order:v2
docker build -t 192.168.10.130/microservice/stock:v2 .
docker push 192.168.10.130/microservice/stock:v2
docker build -t 192.168.10.130/microservice/portal:v2 .
docker push 192.168.10.130/microservice/portal:v2
docker build -t 192.168.10.130/microservice/gateway:v2 .
docker push 192.168.10.130/microservice/gateway:v2
docker build -t 192.168.10.130/microservice/eureka:v2 .
docker push 192.168.10.130/microservice/eureka:v2

# 重新通过yaml进行部署
...略过

CATALOG
  1. 1. 微服务架构
  2. 2. 常见微服务框架
  3. 3. springcloud组件简单介绍
    1. 3.1. Eureka服务发现
    2. 3.2. Ribbon负载均衡
    3. 3.3. Zuul网关
    4. 3.4. Hystrix熔断器
    5. 3.5. springcloud gateway API网关
    6. 3.6. SpringCloud Config配置中心
  4. 4. 迁移
    1. 4.1. 安装mysql
    2. 4.2. 安装openjdk和maven
    3. 4.3. 部署eureka服务
    4. 4.4. 部署gateway服务
    5. 4.5. 部署portal前端服务
    6. 4.6. 部署order订单服务
    7. 4.7. 部署product产品服务
    8. 4.8. 部署stock库存服务
  5. 5. 全链路监控————pinpoint
    1. 5.1. 常见的全链路监控工具
    2. 5.2. pinpoint全链路监控安装部署