开始
接下来开始动手实践吧。这里我选用阿里云 MSE+ACK 组合做完整的方案。
环境准备
首先,购买好一套 MSE 注册配置中心专业版,和一套 MSE 云原生网关。这边不介绍具体的购买流程。
在应用部署前,提前准备好配置。这边我们可以先配置 A 的下游是 C,B 的下游也是 C。
部署应用
接下来我们基于 ACK 部署三个应用。可以从下面的配置看到,应用 A 这个版本spring-cloud-a-b,推空保护开关已经打开。
这里 demo 选用的 nacos 客户端版本是 1.4.2,因为推空保护在这个版本之后才支持。
配置示意(无法直接使用):
# A 应用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a
name: spring-cloud-a-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: spring.cloud.nacos.discovery.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.config.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.discovery.metadata.version
value: base
- name: spring.application.name
value: sc-A
- name: spring.cloud.nacos.discovery.namingPushEmptyProtection
value: "true"
image: mse-demo/demo:1.4.2
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: spring.cloud.nacos.discovery.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.config.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.discovery.metadata.version
value: base
- name: spring.application.name
value: sc-A
image: mse-demo/demo:1.4.2
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# B 应用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
strategy:
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-b
labels:
app: spring-cloud-b
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: spring.cloud.nacos.discovery.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.config.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.application.name
value: sc-B
image: mse-demo/demo:1.4.2
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
# C 应用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: spring.cloud.nacos.discovery.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.cloud.nacos.config.server-addr
value: mse-xxx-nacos-ans.mse.aliyuncs.com:8848
- name: spring.application.name
value: sc-C
image: mse-demo/demo:1.4.2
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
部署应用:
在网关注册服务
应用部署好之后,在 MSE 云原生网关中,关联上 MSE 的注册中心,并将服务注册进来。
我们设计的是网关只调用 A,所以只需要将 A 放进来注册进来即可。
验证和调整链路
基于 curl 命令验证一下链路:
$ curl http://${网关IP}/ip
sc-A[192.168.1.194] --> sc-C[192.168.1.195]
验证一下链路。可以看到这时候 A 调用的是 C,我们将配置做一下变更,实时地将 A 的下游改为 B。
再看一下,这时三个应用的调用关系是 ABC,符合我们之前的计划。
$ curl http://${网关IP}/ip
sc-A[192.168.1.194] --> sc-B[192.168.1.191] --> sc-C[192.168.1.180]
接下来,我们通过一段命令,连续地调用接口,模拟真实场景下不间断的业务流量。
$ while true; do sleep .1 ; curl -so /dev/null http://${网关IP}/ip ;done
观测调用
通过网关监控大盘,可以观察到成功率。
注入故障
一切正常,现在我们可以开始注入故障。
这里我们可以使用 K8s 的 NetworkPolicy 的机制,模拟出口网络异常。
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: block-registry-from-b
spec:
podSelector:
matchLabels:
app: spring-cloud-b
ingress:
- {}
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 8080
这个 8080 端口的意思是,不影响内网调用下游的应用端口,只禁用其它出口流量(比如到达注册中心的 8848 端口就被禁用了)。这里 B 的下游是 C。
网络切断后,注册中心的心跳续约不上,过一会儿(30 秒后)就会将应用 B 的所有 IP 摘除。
再次观测
再观察大盘数据库,成功率开始下降,这时候,在控制台上已经看不到应用 B 的 IP 了。
回到大盘,成功率在 50% 附近不再波动。
小结
通过实践,我们模拟了一次真实的风险发生的场景,并且通过客户端的高可用方案(推空保护),成功实现了对风险的控制,防止服务调用的发生异常。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理