K8S圣经12:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
Posted 疯狂创客圈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8S圣经12:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布相关的知识,希望对你有一定的参考价值。
文章很长,持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 :
免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备
免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,完成职业升级, 薪酬猛涨!加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷1)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷2)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷3)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取
SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
尼恩的技术社群中(50+),尼恩一直到指导大家面试, 指导大家做简历优化。
生产环境 ,如何进行SpringCloud+Jenkins+ K8s Ingress 灰度发布, 是很多小伙伴都没有实操过的难题。
但是,灰度实操,又是高级开发,和架构师的必须课。 很多小伙伴,由于不懂灰度,不懂云原生,错失了高级开发或者架构师岗位,实在非常可惜。
所以,尼恩基于《K8S学习圣经》, 为大家系统化从原理到实操,介绍一下SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布。作为《K8S学习圣经》的12部分。
《K8S学习圣经》的组成
- 第一部分:云原生(Cloud Native)的原理与演进
- 第二部分:穿透K8S的8大宏观架构
- 第三部分:最小化K8s环境实操
- 第四部分:Kubernetes 基本概念
- 第五部分:Kubernetes 工作负载
- 第六部分:Kubernetes 的资源控制
- 第七部分: SVC负载均衡底层原理
- 第八部分: Ingress底层原理和实操
- 第九部分: 蓝绿发布、金丝雀发布、滚动发布、A/B测试 实操
- 第十部分: 服务网格Service Mesh 宏观架构模式和实操
- 第十一部分: 使用K8S+Harber 手动部署 Springboot 应用
- 第十二部分: SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
- 第十三部分: k8s springboot 生产实践(高可用部署、基于qps动态扩缩容、prometheus监控)
- 第十四部分:k8s生产环境容器内部JVM参数配置解析及优化
米饭要一口一口的吃,不能急。
结合《K8S学习圣经》,尼恩从架构师视角出发,左手云原生+右手大数据 +SpringCloud Alibaba 微服务 核心原理做一个宏观的介绍。由于内容确实太多, 所以写多个pdf 电子书:
(1) 《 Docker 学习圣经 》PDF (V1已经完成)
(2) 《 SpringCloud Alibaba 微服务 学习圣经 》PDF (V1已经完成)
(3) 《 K8S 学习圣经 》PDF (coding…)
(4) 《 flink + hbase 学习圣经 》PDF (planning …)
以上学习圣经,并且后续会持续升级,从V1版本一直迭代发布。 就像咱们的《 尼恩 Java 面试宝典 》一样, 已经迭代到V60啦。
40岁老架构师尼恩的掏心窝: 通过一系列的学习圣经,带大家穿透“左手云原生+右手大数据 +SpringCloud Alibaba 微服务“ ,实现技术 自由 ,走向颠覆人生,让大家不迷路。
本PDF 《K8S 学习圣经》完整版PDF的 V1版本,后面会持续迭代和升级。供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
以上学习圣经的 基础知识是 尼恩的 《高并发三部曲》,建议在看 学习圣经之前,一定把尼恩的《 Java高并发三部曲 》过一遍,切记,切记。
本部分目录(第12部分)
如何进行 SpringCloud+Jenkins+ K8s Ingress 灰度发布?
生产环境 ,如何进行SpringCloud+Jenkins+ K8s Ingress 灰度发布, 是很多小伙伴都没有实操过的难题。
但是,这些又是高级开发,和架构师的必须课。
在 Kubernetes 上的应用实现灰度发布,最简单的方案是引入官方的 Nginx-ingress
来实现。我们通过部署两套 deployment 和 services,分别代表灰度环境和生产环境,通过负载均衡算法,实现对两套环境的按照灰度比例进行分流,进而实现灰度发布。
通常的做法是当项目打包新镜像后,通过修改 yaml
文件的镜像版本,执行 kubectl apply
的方式来更新服务。
如果发布流程还需要进行灰度发布,那么可以通过调整两套服务的配置文件权重来控制灰度发布,这种方式离不开人工执行。
那么,有没有一种方式能够实现逐步灰度呢?比如自动将灰度比例从 10% 权重提高到 100%,且并且出现问题秒级回退.
答案是肯定的,利用 jenkins 就能够满足此类需求。
本文,为大家介绍一下,SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布
回顾 Nginx-ingress 架构和原理
回顾一下 Nginx-ingress
的架构和实现原理:
Nginx-ingress
通过前置的 Loadbalancer
类型的 Service
接收集群流量,将流量转发至 Nginx-ingress
Pod 内并对配置的策略进行检查,再转发至目标 Service
,最终将流量转发至业务容器。
传统的 Nginx
需要我们配置 conf
文件策略。
但 Nginx-ingress
通过实现 Nginx-ingress-Controller
将原生 conf
配置文件和 yaml
配置文件进行了转化,当我们配置 yaml
文件的策略后,Nginx-ingress-Controller
将对其进行转化,并且动态更新策略,动态 Reload Nginx Pod
,实现自动管理。
那么 Nginx-ingress-Controller
如何能够动态感知集群的策略变化呢?
方法有很多种,可以通过 webhook admission 拦截器,也可以通过 ServiceAccount 与 Kubernetes Api 进行交互,动态获取。
Nginx-ingress-Controller
使用后者来实现。所以在部署 Nginx-ingress
我们会发现 Deployment
内指定了 Pod 的 ServiceAccount,以及实现了 RoleBinding ,最终达到 Pod 能够与 Kubernetes Api 交互的目的。
灰度实操之前的准备
部署一套稳定版本的 deployment 和 svc
然后再部署一套灰度版本的 deployment 和 svc
在进行流量的分发测试
部署和测试 stable 版本的 deployment 和 svc
kubectl apply -f app-service.yaml
部署一下
访问一下
curl http://192.168.49.2:30808
部署和测试 canary版本的 deployment 和 svc
canary版本 的 deployment 和 svc
kubectl apply -f app-service.yaml
部署一下
访问一下
curl http://192.168.49.2:30909
以上具体的实操过程, 请参见 尼恩的 《穿透云原生视频》
基于用户的灰度场景
简单的基于用户的发布场景, ingress 需要加上注解:
nginx.ingress.kubernetes.io/canary:"true"
nginxingress.kubernetes.io/canary-by-header:"canary"
用户的Request Header 的值有一个 canary header,当 canary header的值:
当 设置为 always时,请求将会被一直发送到 Canary 版本;
当 设置为 never时,请求不会被发送到 Canary 入口;
对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。
具体如下图:
如果用户要自定义 Request Header 的值,必须与canary-by-header 注解(annotation )一起使用。
这里的例子,使用 nginx.ingress.kubernetes.io/canary-by-header
,自定义 Request Header 进行流量切分,适用于灰度发布以及 A/B 测试。
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "region"
nginx.ingress.kubernetes.io/canary-by-header-value: "beijing"
此灰度规则为:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。
如果按照的配置,
当 Request Header的 region 设置为 beijing时,请求将会被一直发送到 Canary 版本;
当 Request Header 没有 region,或者 设置为非 beijing时,请求不会被发送到 Canary 入口;
接下来,开始基于 用户的灰度实操
配置stable版本的ingress
配置canary版本的ingress
当我们访问的时候不带header,则只会访问stable版本应用,如下:
while sleep 1; do curl http://foo.bar.com/ | egrep flag; done
如果我们在访问的时候带上region: sichuan 的header,则只会访问到canary版本应用,如下:
while sleep 1; do curl http://foo.bar.com/ -H "region: beijing" | egrep flag; done
以上具体的实操过程, 请参见 尼恩的 《穿透云原生视频》
基于权重的灰度场景
基于权重的 Canary 规则
使用 nginx.ingress.kubernetes.io/canary-weight
注解:
基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。
权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。
权重为 100 意味着所有请求都将被发送到 Canary 入口。
基于权重的发布实操
(1)配置stable版本的ingress
同基于用户的灰度场景,这里不做赘述
(2)配置canary版本的ingress
具体如下。 源文件可以找尼恩获取。
(3) 启动 基于权重的灰度 ingress
(4)然后我们通过访问测试,效果如下:
while sleep 1; do curl http://foo.bar.com/ | egrep flag; done
以上具体的灰度实操过程, 请参见 尼恩的 《穿透云原生视频》
如何进行自动化灰度?
在生产环境,通过上面的手工命令,一行一行的执行是不现实的
需要借助自动化的流水线
jenkins 安装和 pipeline 流水线的使用
Jenkins pipeline是基于Groovy语言实现的DSL,用于描述流水线如何进行,包括编译、打包、部署、测试等等步骤
此处我们使用离线安装包方式安装/docker-compose 的方式安装
Jenkins 官网:https://www.jenkins.io
官方安装文档指导:https://www.jenkins.io/doc/book/installing/
下载和启动 jenkins
这里简单介绍一下 Jenkins 的本机部署方式.
一般都是下载一个 Jenkins 的 war, 修改配置文件中的 JDK 路径, 然后 service start 就可以正常使用了.
我们在服务器上执行如下命令进行jenkins可运行包下载
mkdir -p /usr/local/jenkins
cd /usr/local/jenkins
下载这个包 https://get.jenkins.io/war-stable/2.375.1/jenkins.war
复制Jenkins war包到 安装目录
cp /vagrant/chapter28/jenkins.2.375.1.war .
找一个 start-jenkins.sh 脚本去启动jenkins。这个shell 和springboot的启动脚本一样,启动命令可以接参数start|restart|stop 分别标识启动,重启,停止服务
复制启动脚本到 安装目录
cp /vagrant/chapter28/deploy_jenkins.sh .
脚本内容如下:
给启动脚本执行权限,并启动jenkins
chmod +x start-jenkins.sh
sh start-jenkins start
查看日志
tail -f nohup.out
这种方式部署简单, 但是容易将我们的服务器环境变得十分复杂.
所以下面介绍本节docker-compose 搭建 Jenkins.
尼恩的环境,首先使用的这种方式。但是发现一个问题,新版本的 jenkins 需要依赖 jdk11, jkd8 不能用了
而尼恩的 公司有要求,一定要用jkd8
所以只能用 docker 安装 jenkins ,实现jdk的隔离。
docker-compose 编排文件 如下:
volumes:
#Jenkins 工作目录,主要存储数据( /user/data/jenkins,安装后初始化密码也在此处 /secrets/initialAdminPassword )
- ./data:/var/jenkins_home\'
#将主机的Docker套接字装入容器中,这将允许Jenkins容器使用主机的Docker守护进程来构建映像并运行容器。
- \'/var/run/docker.sock:/var/run/docker.sock\'
#容器内可共享宿主机的 docker
- \'/usr/bin/docker:/usr/bin/docker\'
#容器内享有 宿主机的docker-compose 环境
- \'/usr/local/bin/docker-compose:/usr/local/bin/docker-compose\'
使用尼恩的一键启动shell脚本,一键启动
具体实操,请参见尼恩视频
首次登录需要查看初始化密码:( 挂载数据文件内可以查看 )
cat ./secrets/initialAdminPassword
需要修改插件的镜像源地址为
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
具体的修改方式为,修改
修改后,重新启动,就可以从清华大学的插件镜像站,下载插件了
接下来访问 jenkins
登录 jenkins
查看启动日志,看到初始化管理员密码数据即表示启动成功,
copy对应的密码,通过ip+port方式进行访问,
上面shell 脚本中指定的端口为8980,我们在启动日志中也能够看到启动的端口为8090。
在浏览器中输入:
http://cdh1:8980
终于看到jenkins的登录界面
输入密码后,安装插件
点击选择插件来安装,然后取消掉几个默认安装的插件
插件安装完毕,有几个失败的,无所谓
关键是 pipeline 插件安装好了就行
接下来,创建第一个管理员用户
全部填 admin
进行一下实例配置
保存后完成
使用 pipeline 插件
Jenkins Pipeline是一套插件,支持在Jenkins中实施和集成持续交付管道。pipeline是部署流水线,它支持脚本和声明式语法,能够比较高自由度的构建jenkins任务.个人推荐使用这种方式去构建jenkins。
Pipeline在Jenkins上增加了一套强大的自动化工具,支持从简单的持续集成到全面的CD管道的用例。通过对一系列相关任务建模,用户可以利用Pipeline的更多功能,如:
- 可维护:管道是在代码中实现的,并且通常会被签入源代码管理,从而使团队能够编辑,审阅和迭代他们的交付管道。
- 可能出现:在继续进行管道运行之前,管道可以选择停止并等待人员输入或批准。
- 复杂场景:管道支持复杂的实际CD需求,包括分叉/连接,循环和并行执行工作的能力。
- 可扩展性:Pipeline插件支持对其DSL的定制扩展 。
一次持续交付(CD)管道是从用户到版本控制软件的自动化表达。对软件的每一次改变(在源代码控制中提交)都会在发布过程中经历一个复杂的过程。
这个过程包括以可靠和可重复的方式构建软件,以及通过测试和部署的多个阶段来推进构建的软件(称为“构建”)。
Pipeline提供了一套可扩展的工具,用于通过管道域特定语言(DSL)语法将“简单到复杂”的交付管道使用“代码”建模 。
安装 Pipeline 插件
如果没有安装 Pipeline 插件,那么还需要单独安装 Jenkins Pipeline 插件
注意,默认 Jenkins 使用 https://updates.jenkins.io/update-center.json 下载并安装扩展,但是速度较慢。
我们可以修改为使用国内镜像站点,比如清华大学镜像站点:
1)Manage Jenkins / Manage Plugins / Advanced
2)Update Site / URL https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
3)Submit
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
pipeline 的 hello world
pipeline是部署流水线,它支持脚本和声明式语法。
通过界面手动配置来配置CD过程,想要配置一些复杂度高的任务,只能选择自由风格的项目,通过选项等操作进行配置,让jenkins可以下载代码、编译构建、然后部署到远程服务器,这样显然是不方便管理和移植的。
pipeline可以创建一个jenkinsfile来申明一个任务,方便管理和移植。
接下来我们创建一个最简单的pipeline。
登录jenkins,点击创建item:
在流水线中选择hello world 生成代码:
以上便是一个最简单的流水线。
点击build now (立即构建),jenkins任务开始执行,运行完成后点击查看执行记录:
在console output 中可以看到运行记录:
为了提高流水线的复用性以及便于流水线代码的管理,更多的是将pipeline的脚本在远程git仓库,当我们修改了远程仓库的流水线脚本,jenkins就会加载到最新的脚本执行。
在流水线配置中选择pipeline script from SCM:
按照提示配置好脚本git仓库地址,访问仓库的凭证,流水线脚本文件的名称(默认是Jenkinsfile),分支(默认是master)等。
配置完成后在仓库中添加文件Jenkinsfile把脚本提交并push, 最后执行任务,发现执行成功。
通过这个特性,我们可以把我们的流水线脚本和项目代码本身放到一个仓库中管理,达到多版本控制并和代码版本统一的效果。
如果我们编写jenkinsfile需要语法提示相关的编辑器,可以使用jenkins官方提供的vscode插件Jenkins Pipeline Linter Connector 。
使用idea Groovy 也能提示部分语法。
idea 设置jenkinsfile 语法提示方法 settings > editor > File Types > Groovy 新增一列Jenkinsfile.
pipeline 语法介绍
jenkins pipeline有2种语法:脚本式(Scripted)语法和声明式(Declar-ative)语法。
pipeline插件从2.5版本开始同时支持两种语法,官方推荐的是使用申明式语法,
在这里也只对申明式语法进行介绍。
申明式语法demo:
pipeline
agent any
stages
stage(\'pull\')
steps
echo \'拉取代码\'
stage(\'build\')
steps
echo \'构建代码\'
声明式语法中,以下结构是必须的,缺少就会报错:
- pipeline:固定语法,代表整条流水线
- agent 执行代理人:指定流水线在哪执行,
默认any即可,也可以指定在docker、虚拟机等等里执行
- environment 环境变量,类似全局变量
environment
//构建执行者
BUILD_USER = ""
- triggers 构建触发器,Jenkins自动构建条件
triggers
//每3分钟判断一次代码是否有变化
pollSCM(\'H/3 * * * *\')
-
stages:流水线阶段集合节点
该节点中至少有一个stage
-
stage:流水线的阶段节点
每个阶段中至少包含一个steps
-
steps:执行步骤集合
每个集合至少包含一个step。
-
step: 执行步骤。
下面是一个比较大的例子
pipeline
//代理,通常是一个机器或容器
agent any
//环境变量,类似全局变量
environment
//构建执行者
BUILD_USER = ""
//构建触发器,Jenkins自动构建条件
triggers
//每3分钟判断一次代码是否有变化
pollSCM(\'H/3 * * * *\')
stages
//构建阶段
stage(\'Build\')
//使用build user vars插件,获取构建执行者
steps
wrap([$class: \'BuildUser\'])
script
//将构建执行者注入到环境变量中,方便最后通知使用
BUILD_USER = "$env.BUILD_USER"
/* 从Bitbucket上拉取分支
* @url git地址
* @branch 分支名称
* @credentialsId Jenkins凭证Id,用于远程访问
*/
git(url: \'https://demo@bitbucket.org/demo/demo.git\', branch: \'master\', credentialsId: \'Bitbucket\')
//执行maven打包
//-B --batch-mode 在非交互(批处理)模式下运行(该模式下,当Mven需要输入时,它不会停下来接受用户的输入,而是使用合理的默认值);
//打包时跳过JUnit测试用例,
//-DskipTests 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下
//-Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类
sh \'npm install && npm run build\'
//部署阶段
stage(\'Deliver\')
steps
//执行脚本
sh \'\'\'
cd /var/lib/jenkins/workspace/demo/
tar -cvf dist.tar.gz ./dist
\'\'\'
stage(\'SSH\')
steps
script
def remote = [:]
remote.name = \'test\'
remote.host = \'192.168.12.12\'
remote.allowAnyHosts = true
withCredentials([usernamePassword(credentialsId: \'192.168.12.12\', passwordVariable: \'password\', usernameVariable: \'username\')])
remote.user = "$username"
remote.password = "$password"
sshCommand remote: remote, command: "pwd"
sshRemove remote: remote, path: \'/usr/share/nginx/html/demo/dist\'
sshPut remote: remote, from: \'/var/lib/jenkins/workspace/demo/dist.tar.gz\', into: \'/usr/share/nginx/html/test-monitor/\'
sshCommand remote: remote, command: "cd /usr/share/nginx/html/demo/ && tar -xvf ./dist.tar.gz"
Jenkins 插件 SSH Pipeline Steps
安装插件 SSH Pipeline Steps, 以支持 跨机器执行脚本。
此插件可通过SSH在远程服务器执行命令和传输文件。
sshCommand 在远程节点上执行给定的命令并响应输出
node
def remote = [:]
remote.name = \'root\'
remote.host = \'cdh1\'
remote.user = \'root\'
remote.password = \'vagrant\'
remote.allowAnyHosts = true
stage(\'Remote SSH\')
sshCommand remote: remote, command: "ls -lrt"
sshCommand remote: remote, command: "for i in 1..5; do echo -n \\"Loop \\$i \\"; date ; sleep 1; done"
sshGet 从远程主机获取文件或目录
node
def remote = [:]
remote.name = \'test\'
remote.host = \'test.domain.com\'
remote.user = \'root\'
remote.password = \'password\'
remote.allowAnyHosts = true
stage(\'Remote SSH\')
sshGet remote: remote, from: \'abc.sh\', into: \'abc_get.sh\', override: true
sshPut 将文件或目录放入远程主机
node
def remote = [:]
remote.name = \'test\'
remote.host = \'test.domain.com\'
remote.user = \'root\'
remote.password = \'password\'
remote.allowAnyHosts = true
stage(\'Remote SSH\')
writeFile file: \'abc.sh\', text: \'ls -lrt\'
sshPut remote: remote, from: \'abc.sh\', into: \'.\'
sshRemove 删除远程主机上的文件或目录
node
def remote = [:]
remote.name = \'test\'
remote.host = \'test.domain.com\'
remote.user = \'root\'
remote.password = \'password\'
remote.allowAnyHosts = true
stage(\'Remote SSH\')
sshRemove remote: remote, path: "abc.sh"
sshScript 在远程节点上执行给定的脚本(文件)并响应输出
node
def remote = [:]
remote.name = \'test\'
remote.host = \'test.domain.com\'
remote.user = \'root\'
remote.password = \'password\'
remote.allowAnyHosts = true
stage(\'Remote SSH\')
writeFile file: \'abc.sh\', text: \'ls -lrt\'
sshScript remote: remote, script: "abc.sh"
结合 withCredentials 从 Jenkins 凭证存储中读取私钥
为了提高安全性,可以用Credentials Plugin屏蔽用户名密码。
def remote = [:]
remote.name = "node-1"
remote.host = "10.000.000.153"
remote.allowAnyHosts = true
node
withCredentials([sshUserPrivateKey(credentialsId: \'sshUser\', keyFileVariable: \'identity\', passphraseVariable: \'\', usernameVariable: \'userName\')])
remote.user = userName
remote.identityFile = identity
stage("SSH Steps Rocks!")
writeFile file: \'abc.sh\', text: \'ls\'
sshCommand remote: remote, command: \'for i in 1..5; do echo -n \\"Loop \\$i \\"; date ; sleep 1; done\'
sshPut remote: remote, from: \'abc.sh\', into: \'.\'
sshGet remote: remote, from: \'abc.sh\', into: \'bac.sh\', override: true
sshScript remote: remote, script: \'abc.sh\'
sshRemove remote: remote, path: \'abc.sh\'
pipeline支持的指令
pipeline的基本结构满足不了现实多变的需求。所以,jenkins pipeline通过各种指令(directive)来丰富自己。
Jenkins pipeline支持的指令有:
- environment:用于设置环境变量,可定义在stage或pipeline部分
- tools:可定义在pipeline或stage部分。它会自动下载并安装我们指定的工具,并将其加入PATH变量中
- input:定义在stage部分,会暂停pipeline,提示你输入内容
- options:用于配置jenkins pipeline本身的选项,比如options retry(3) 表示,当pipeline失败时再重试2次。options指令可定义在stage或pipeline部分
- parallel:并行执行多个step。
- parameters:与input不同,parameters是执行pipeline前传入的一些参数
- triggers:用于定义执行pipeline的触发器
- when:当满足when定义的条件时,阶段才执行。
ingress 灰度发布流水线设计
在使用ingress 进行灰度之前,直接使用service+deployment的方式进行灰度。这种场景下,可以 通过不同的镜像(含deployment)来进行灰度大概的流程如下:
- 发布canary版本应用进行测试
- 测试完成将canary版本替换成stable版本
- 删除canary版本的ingress配置
- 删除老的stable版本
整个过程中,对于已经部署好的deployment是不能直接修改labels标签的。
所以,在canary版本测试完成后,还要更新stable版本的镜像。当然,可以使用滚动更新的方式去完成。那我们流水线可以这样设计,如下:
在使用ingress 进行灰度之后,灰度测试通过之后,就使用灰度镜像作为new stable 镜像使用,不需要重新的打包镜像,
但是在发布期间,线上同时会存在旧的 old stable 和 canary 两套镜像, 虽然浪费一些资源,但是好处随时可以回退。
其实尼恩告大家,版本的发布是惊心动魄, 回退的概率非常大。 同时存在两套版本,实现s级回退, 也是一件非常爽的事情。
在使用ingress 进行灰度之后,灰度的流程,可以变得更加灵活,更加丰富,更加稳健。
在使用ingress 进行灰度 ,总体流程为3部分,大致如下:
CICD 流水线预览
为了实现以上目标,我们设计了以下持续部署流水线。
AB测试和灰度,部署流水线主要实现了以下几个步骤:
1、自动化的制品发布,通过gitlab进行自动化打包之后,通过钩子方法触发流水线,打包镜像到harber仓库
2、生产环境进行 A/B 测试
3、生产环境自动灰度发布(自动进行4次逐渐提升灰度比例)
4、生产环境进行版本正式切换
step1:自动化的制品发布
自动化的制品发布流程图:
从 Gitlab 提交代码到自动触发持续集成的步骤:
1、提交代码后触发持续集成,自动构建镜像
2、镜像构建完成后,自动推送镜像到制品库
3、触发持续部署
在gitlab上, 有回调jenkins的hook 链接设置,设置之后,可以触发 jenkins 的 自动化制品构建流水线。
这里的制品就是docker 镜像。 制品的 仓库就是harber。
模拟的 制品构建流水线如下
具体的步骤,大概如下:
1、克隆 springboot代码项目到本地
stage(\'Clone\')
echo "1.Clone Stage"
git url: "https://gitee.com/xujk-27400861/springboot-dubbo.git"
script
build_tag = sh(returnStdout: true, script: \'git rev-parse --short HEAD\').trim()
echo "$build_tag"
2、maven构建springboot代码项目
编写脚本,因为我们要编译构建项目的子项目,所以需要跳转到子目录去构建
stage(\'执行构建\')
container(\'maven\')
sh "mvn --version"
sh \'pwd\'
sh \'\'\'cd provider/
mvn clean package -DskipTests\'\'\'
//sh \'mvn package\'
echo \'构建完成\'
provider/为项目子目录,我们要编译的项目;-DskipTests参数,表示跳过代码测试
3、构建docker镜像
编写脚本,构建docker镜像;
stage(\'Build\')
echo "3.Build Stage"
container(\'docker\')
sh "docker -v"
sh \'pwd\'
sh """cd /home/jenkins/agent/workspace/linetest/provider/
ls
docker build -t xjk27400861/springbootapp:$build_tag ."""
4、推送docker镜像到harber上,完成制品发布
编写脚本,推送docker镜像;
stage(\'Push\')
echo "4.Push Docker Image Stage"
container(\'docker\')
sh "docker login --username=xjk27400861 -p xujingkun@123"
sh "docker push xjk27400861/springbootapp:$build_tag"
具体的实操,请参见 尼恩的云原生视频。
step2:生产环境进行 A/B 测试
进行 A/B 测试流程如下:
进行 A/B 测试时,只有 Header 包含 location=beijing 可以访问新版本,其他用户访问生产环境仍然为旧版本。
或者header可以设置为其他的参数。
这里要注意,可以把参与 A/B 测试 的用户,在数据库里边进行配置, 前端能带有AB测试的标志。
AB测试手动触发,流水线比较简单。
发布AB测试的ingress之后, 流量分发的架构图如下:
A/B 测试原理:
部署了两套应用,一套旧的稳定的stable应用,一套新版canary 灰度应用。
新旧的应用都配置了ingress相同的host。
而新的ingress还添加了注解canary:true 代表开启使用灰度发布
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "region"
nginx.ingress.kubernetes.io/canary-by-header-value: "beijing"
只有 Header 包含 location=beijing 的流量是会从new-ingress这个ingress进来访问新版本应用。
其他流量从old-ingress的ingress去访问老版本的应用。
具体的实操,请参见 尼恩的云原生视频。
step3:生产环境进行 A/B 测试
在AB测试通过之后,可以结束ab测试的ingress,通过 流水线结束。
接下来,开始灰度,一共四轮灰度
第一次灰度:新版本 30% 的灰度比例,此时访问生产环境大约有 30% 的流量进入新版本灰度环境:
30s 后自动进行第二轮灰度:新版本 60% 的灰度比例:
60s 后自动进行第三轮灰度:新版本 90% 的灰度比例:
60s 后自动进行第四轮灰度:新版本 100% 的灰度比例:
每一轮灰度,可以两种方式步进:
(1) 人工确认:是否自动灰度发布, 流水线上设置确认按钮, 单击确认进入下一步
(2) 定时步进:流水线上设置时间,比如每轮间隔 30s
本案例中,配置了定时步进方式,渐进式进行,每次持续 30s 后自动进入下一个灰度阶段。
灰度过程中的流量架构图,大致如下:
在不同的灰度阶段,会发现请求新版本出现的概率越来越高。
灰度流水线的示意图如下;
如果过程当中需要回退,可以结束流水线,然后执行 灰度撤销流水线。
灰度撤销流水线的示意图,大致如下
jenkins 流水线上,更多的是shell脚本的编写
由此可见,shell脚本的编写能力,是多么重要
具体的实操,请参见 尼恩的云原生视频。
step4:生产环境进行版本正式切换
灰度版本稳定一段时间之后, 进行善后的工作
把老的稳定版本去掉, 完成生产环境进行版本正式切换
流程图如下:
步骤:
1、把stable-service指向访问cannary-deloyment
应为canary 已经足够稳定了
2、删除canary-ingress
不需要 灰度的ingress 了
3、删除canary-service
不需要灰度的svc 了
4、删除stable-deployment
不需要 老的stable-deployment 了
canary deployment 已经足够稳定了,已经编程新的stable deployment
具体的实操,请参见 尼恩的云原生视频。
最后总结一下
上面的灰度流程, 很多环节也是手动的,需要人工参与的。
如果不需要手动参与,可以使用argo-rollouts结合argocd进行灰度发布,argo-rollouts自定义了一套CRD用于控制发布流程,可以省去很多手动操作过程,argocd是基于gitops实现的一套软件,便于我们进行CD控制,也提供了UI面板进行操作。
但是线上发布, 是非常重要,非常谨慎的一个操作。
而且很容易出问题,及时有预发布环境, 也容易出问题, 常常出现紧急回退的场景。
在尼恩亲手尽力的几百次发布过程中, 回退是大概率事件。
常常进行版本回退。
所以,不建议使用全自动的发布流程,全自动无值守,往往意味着高风险。
一句话:背锅的滋味,不好受呀。
技术自由的实现路径:
实现你的 架构自由:
《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》
《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》
… 更多架构文章,正在添加中
实现你的 响应式 自由:
这是老版本 《Flux、Mono、Reactor 实战(史上最全)》
实现你的 spring cloud 自由:
《Spring cloud Alibaba 学习圣经》 PDF
《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》
《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》
实现你的 linux 自由:
实现你的 网络 自由:
《网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!》
实现你的 分布式锁 自由:
实现你的 王者组件 自由:
《队列之王: Disruptor 原理、架构、源码 一文穿透》
《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》
《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》
实现你的 面试题 自由:
SpringCloud Alibaba 学习圣经,10万字实现 SpringCloud 自由
40岁老架构师尼恩的掏心窝:
现在拿到offer超级难,甚至连面试电话,一个都搞不到。
尼恩的技术社群中(50+),很多小伙伴凭借 “左手云原生+右手大数据 +SpringCloud Alibaba 微服务“三大绝活,拿到了offer,并且是非常优质的offer,据说年终奖都足足18个月 ,非常令人羡慕。
问题是:“左手云原生+右手大数据 +SpringCloud Alibaba 微服务“ 内容非常多,实操的环境非常复杂,底层原理很深。
米饭要一口一口的吃,不能急。在这里,尼恩从架构师视角出发,左手云原生+右手大数据 +SpringCloud Alibaba 微服务 核心原理做一个宏观的介绍。
由于内容确实太多, 所以写多个pdf 电子书:
(1) 《 Docker 学习圣经 》PDF (V1已经完成)
(2) 《 SpringCloud Alibaba 微服务 学习圣经 》PDF (V1已经完成)
(3) 《 K8S 学习圣经 》PDF (coding…)
(4) 《 flink + hbase 学习圣经 》PDF (planning …)
以上学习圣经,并且后续会持续升级,从V1版本一直迭代发布。 就像咱们的《尼恩 Java 面试宝典》一样, 已经迭代到V60啦。
40岁老架构师尼恩的掏心窝: 通过一系列的学习圣经,带大家穿透“左手云原生+右手大数据 +SpringCloud Alibaba 微服务“ ,实现技术 自由 ,走向颠覆人生,让大家不迷路。
本PDF 《SpringCloud Alibaba 微服务 学习圣经》完整版PDF的 V1版本,后面会持续迭代和升级。供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
以上学习圣经的 基础知识是 尼恩的 高并发三部曲,建议在看 学习圣经之前,一定把尼恩的 Java高并发三部曲过一遍,切记,切记。
注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取:码云
《 SpringCloud Alibaba 微服务 学习圣经 》PDF 封面
《 SpringCloud Alibaba 微服务 学习圣经 》目录
- 40岁老架构师尼恩的掏心窝:
- 当前版本V1
- 一键导入 SpringCloud 开发环境 (地表最强)
- 环境准备
- 一键导入OR自己折腾
- 随书源码 crazy-springcloud 脚手架涉以及基础中间件
- 微服务 分布式系统的架构12次演进
- 微服务 分布式系统的几个基础概念
- 架构演进1:单机架构
- 架构演进2:引入缓存架构
- 架构演进3:接入层引入反向代理实现负载均衡
- 架构演进4:数据库读写分离
- 架构演进5:数据库按业务分库
- 架构演进6:使用LVS或F5接入层负载均衡
- 架构演进7:通过DNS轮询实现机房间的负载均衡
- 架构演进8:引入NoSQL数据库和搜索引擎等技术
- 架构演进9:大应用拆分为微服务
- 架构演进10:引入企业服务总线ESB对微服务进行编排
- 架构演进11:引入容器化技术实现动态扩容和缩容
- 架构演进12:以云平台承载系统
- 架构演进的涉及的核心知识
- SpringCloud netflix 入门
- SpringCloud 开发脚手架
- 启动Eureka Server 注册中心
- 启动Config 配置中心
- config-server 服务
- 微服务入门案例
- uaa-provider 微服务提供者
- uaa-provider 实现一个Rest接口
- uaa-provider的运行结果
- demo-provider 完成RPC远程调用
- REST服务的本地代理接口
- 通过REST服务的本地代理接口,进行RPC调用
- 启动demo-provider
- 通过swagger 执行RPC操作
- SpringCloud Eureka 服务注册
- SpringCloud Config 统一配置
- Nacos 服务注册+ 统一配置
- 1、Nacos 优势
- 1.1 与eureka对比
- 1.2 与springcloud config 对比
- 三大优势:
- 2、Spring Cloud Alibaba 套件
- Spring Cloud Alibaba 套件和Spring Cloud Netflix套件类比
- 3、Nacos 的架构和安装
- 3.1 Nacos 的架构
- 3.2 Nacos Server 的下载和安装
- 4、Nacos Server 的运行
- 4.1两种模式
- 4.2 standalone 模式
- 4.3 cluster 模式
- cluster 模式需要依赖 MySQL,然后改两个配置文件:
- 4.4 Nacos Server 的配置数据是存在哪里呢?
- 5、实战1:使用Nacos作为注册中心
- 实战的工程
- 5.1 如何使用Nacos Client组件
- 首先引入 Spring Cloud Alibaba 的 BOM
- 5.2 演示的模块结构
- 5.3 provider 微服务
- step1:在 provider 和 consumer 的 pom 添加以下依赖:
- step2:启动类
- step3:服务提供者的 Rest 服务接口
- step4:配置文件
- step5:启动之后,通过swagger UI访问:
- 5.4 Consumer 微服务演示RPC远程调用
- 消费者的controller 类
- 消费者配置文件
- 通过swagger UI访问消费者:
- 5.5涉及到的演示地址:
- 5.6 Nacos Console
- 6、实战2:使用Nacos作为配置中心
- 6.1 基本概念
- 1)Profile
- 2)Data ID
- 3)Group
- 6.2 通过Nacos的console 去增加配置
- 1)nacos-config-demo-dev.yaml
- 2)nacos-config-demo-sit.yaml
- 6.3 使用Nacos Config Client组件
- 1)加载nacos config 的客户端依赖:
- 启动类
- 控制类:
- 2)bootstrap配置文件
- 6.4 测试结果
- 6.4 可以端如何与服务端的配置文件相互对应
- 6.1 基本概念
- 7、配置的隔离
- 8、nacos集群搭建
- IP规划
- 集群的使用
- 1、Nacos 优势
- Nacos 高可用架构与实操
- 客户端高可用
- 客户端高可用的方式一:配置多个nacos-server
- Nacos Java Client通用参数
- 客户端高可用的方式二:本地缓存文件 Failover 机制
- 本地缓存文件 Failover 机制
- 客户端Naming通用参数
- Nacos两种健康检查模式
- agent上报模式
- 服务端主动检测
- 临时实例
- 注册实例支持ephemeral字段
- 临时实例和持久化实例区别
- Nacos Server运行模式
- Nacos CP/AP模式设定
- Nacos CP/AP模式切换
- AP/CP的配套一致性协议
- AP模式下的distro 协议
- CP模式下的raft协议
- 集群内部的特殊的心跳同步服务
- 集群部署模式高可用
- 节点数量
- 多可用区部署
- 部署模式
- 高可用nacos的部署架构
- 高可用nacos的部署实操
- 总结
- 客户端高可用
- SpringCloud Feign 实现RPC 远程调用
- SpringCloud + Dubbo 实现RPC 远程调用
- 大背景:全链路异步化的大趋势来了
- SpringCloud + Dubbo 完成 RPC 异步
- Dubbo3应用的宏观架构
- Dubbo3 应用架构的核心组件
- SpringBoot整合Dubbo3.0基础准备
- SpringCloud+Nacos+Dubbo3.0
- 版本说明
- 项目结构介绍
- 1、dubbo的依赖的坐标
- 2、 注册中心的依赖的坐标
- SpringBoot整合Dubbo3.0大致步骤
- 模块结构
- Dubbo微服务注册发现的相关配置
- 命名空间隔离
- 微服务yml配置
- common-service 模块
- 服务提供者实操:dubbo-provider 服务
- pom依赖
- 服务实现类
- dubbo和Feign的一个不同
- Provider的Dubbo+Nacos配置文件
- 启动类 加上@EnableDubbo 注解
- 启动、体验Provider
- 在Nacos查看Dubbo服务的注册情况
- 服务消费者实操:dubbo-consumer 服务
- consumer模块
- 消费者实现类
- 消费者Dubbo+Nacos配置文件
- 启动类 加上@EnableDubbo 注解
- 启动、体验 Consumer
- 在Nacos查看Dubbo服务的注册情况
- Feign+Dubbo性能的对比测试
- Dubbo比Feign高10倍以上的本质
- Dubbo 与 SpringCloud 的通信 Openfeign的区别
- 1、协议支持方面
- 2、通信性能方面
- 3、线程模型方面
- SpringCloud + Dubbo RPC 的集成价值
- hystrix 服务保护
- Sentinel 服务保护
- sentinel 基本概念
- 1、什么是Sentinel:
- Sentinel 具有以下特征:
- Sentinel主要特性:
- Sentinel 的使用
- Sentinel中的管理控制台
- 1 获取 Sentinel 控制台
- 2 sentinel服务启动
- 客户端能接入控制台
- Sentinel与Hystrix的区别
- 2、使用 Sentinel 来进行熔断与限流
- 1)定义资源
- 资源注解@SentinelResource
- @SentinelResource 注解
- fallback 函数签名和位置要求:
- defaultFallback 函数签名要求:
- 2)定义规则
- 1)定义资源
- 3、sentinel 熔断降级
- 1)什么是熔断降级
- 2)熔断降级规则
- 3)几种降级策略
- 4)熔断降级代码实现
- 5)控制台降级规则
- 6)与Hystrix的熔断对比:
- 4、Sentinel 流控(限流)
- 基本的参数
- 流控的几种 strategy:
- 4.1 直接失败模式
- 使用API进行资源定义
- 代码限流规则
- 网页限流规则配置
- 测试
- 4.2 关联模式
- 使用注解进行资源定义
- 代码配置关联限流规则
- 网页限流规则配置
- 测试
- 4.3 Warm up(预热)模式
- 使用注解定义资源
- 代码限流规则
- 网页限流规则配置
- 通过jmeter进行测试
- 4.4 排队等待模式
- 示例
- 使用注解定义资源
- 代码限流规则
- 网页限流规则配置
- 通过jmeter进行测试
- 4.5 热点规则 (ParamFlowRule)
- 自定义资源
- 限流规则代码:
- 网页限流规则配置
- 5、Sentinel 系统保护
- 系统保护的目的
- 系统保护规则的应用
- 网页限流规则配置
- 6、黑白名单规则
- 访问控制规则 (AuthorityRule)
- 7、如何定义资源
- 方式一:主流框架的默认适配
- 方式二:抛出异常的方式定义资源
- 方式三:返回布尔值方式定义资源
- 方式四:注解方式定义资源
- 方式五:异步调用支持
- 8、核心组件
- Resource
- Context
- Context的创建与销毁
- Entry
- DefaultNode
- StatisticNode
- 9、插槽Slot
- NodeSelectorSlot
- 调用链树
- 构造树干
- 创建context
- 创建Entry
- 退出Entry
- 构造叶子节点
- 保存子节点
- ClusterBuilderSlot
- StatistcSlot
- SystemSlot
- AuthoritySlot
- FlowSlot
- DegradeSlot
- DefaultProcessorSlotChain
- slot总结
- 10、sentinel滑动窗口实现原理
- 1)基本原理
- 2)sentinel使用滑动窗口都统计啥
- 3)滑动窗口源码实现
- 3.1)MetricBucket
- 3.2)WindowWrap
- 3.3)LeapArray
- Zuul 微服务网关
- Webflux 响应式编程
- WebFlux 学习前言
- WebFlux 增删改查完整实战 demo
- Dao层 (又称 repository 层)
- entity(又称 PO对象)
- Dao 实现类
- Service服务层
- Controller控制层
- Mono
- Flux
- 使用配置模式进行WebFlux 接口开发
- 处理器类 Handler
- 路由配置
- WebFlux集成Swagger
- maven依赖
- swagger 配置
- WebFlux 测试
- 配置模式的 WebFlux Rest接口测试
- 注解模式的WebFlux Rest接口测试
- swagger 增加界面
- 配置大全
- 静态资源配置
- WebFluxSecurity配置
- WebSession配置
- 文件上传配置
- WebFlux 执行流程
- WebFlux学习提示
- Spring Cloud Gateway 微服务网关
- 1、SpringCloud Gateway 简介
- 1.1 本文姊妹篇 《Flux 和 Mono 、reactor实战 (史上最全)》
- 1.2 SpringCloud Gateway 特征
- 1.3 SpringCloud Gateway和架构
- 1)SpringCloud Zuul的IO模型
- 2)Webflux 服务器
- 3)Spring Cloud Gateway的处理流程
- 2、路由配置方式
- 2.1 基础URI路由配置方式
- 2.2 基于代码的路由配置方式
- 2.3 和注册中心相结合的路由配置方式
- 3、路由 匹配规则
- 说明:
- 3.1 Predicate 断言条件(转发规则)介绍
- 1)通过请求参数匹配
- 2)通过 Header 属性匹配
- 3)通过 Cookie 匹配
- 4)通过 Host 匹配
- 5)通过请求方式匹配
- 6)通过请求路径匹配
- 7)通过请求 ip 地址进行匹配
- 8)组合使用
- 3.2 过滤器规则(Filter)
- 过滤器规则(Filter)
- PrefixPath
- RedirectTo
- RemoveRequestHeader
- RemoveResponseHeader
- RemoveRequestParameter
- RewritePath
- SetPath
- SetRequestHeader
- SetStatus
- StripPrefix
- RequestSize
- Default-filters
- 3.3 通过代码进行配置
- 3.2 实现熔断降级
- 4、高级配置
- 4.1 分布式限流
- 4.2 健康检查配置
- maven依赖
- 配置文件
- 4.3 统一配置跨域请求:
- 5、整合Nacos
- maven依赖
- 服务发现配置:从Nacos获取微服务提供者清单
- nacos实现动态配置
- 服务发现路由predicates和filters的自定义定义
- 为注册中心路由配置断言和过滤器
- 6、整合Swagger聚合微服务系统API文档
- maven依赖
- 配置文件
- 效果:
- 7、Gatway 网关的过滤器开发
- 7.1 过滤器的执行次序
- 7.2定义全局过滤器
- 7.3定义局部过滤器
- 8、整合Sentinel完成流控和降级
- maven依赖
- 配置文件
- 限流规则通用配置
- 限流规则设置
- 网关限流参数
- 1、SpringCloud Gateway 简介
- SpringBoot Admin 进行微服务实例的监控
- 使用SpringBoot Admin 进行日志的记录
- 1、SpringBoot Admin 简介
- 2、使用 SpringBoot Admin 监控服务
- 2.1 导入依赖
- 2.2 配置yml
- 2.3 集成spring security
- 2.4 启动器类
- 2.5、测试
- 3、actuator 启用和暴露端点
- 3.1 启用端点
- 3.2 暴露端点
- 4、微服务Provider改造
- 4.1 导入依赖
- 4.2 配置yml
- 使用context-path
- 加上spring security密码
- 5、admin实现在线日志查看
- 5.1、添加jar包
- 5.2 在application.yml平级文件夹中添加logback-spring.xml配置文件
- 5.3 log.path 如何使用环境变量呢?
- 5.4 actuator的配置
- 测试结果
- 1.不暴露端点 测试
- 2.正常情况
- 6、admin与Nacos(或Eureka)结合的好处
- ELK日志平台(elasticsearch +logstash+kibana)原理和实操
- ELK的关系
- ELK优点
- 简单的ELK日志平台
- ELK改进之引入Filebeat
- ELK的应用场景
- ELK的不足
- es的资源占用
- Elasticsearch概述
- logstash概述
- logstash作用:
- logstash的架构:
- Input(输入):
- Filter(过滤器)
- Output(输出):
- Logstash的角色与不足
- filebeat介绍
- filebeat和beats的关系
- Filebeat是如何工作的
- Filebeat下载页面
- Filebeat文件夹结构
- Filebeat启动命令
- 配置inputs
- Log input
- 配置项
- 管理多行消息
- 配置Logstash output
- 一键安装 es+logstash+ kibana
- 对应的镜像版本
- docker编码文件
- 访问kibana
- 读取filebeat-输出到es集群
- 在kibana显示的效果
- 使用filebeat发送日志
- 制作filebeat镜像
- 制作基础的unbantu镜像
- 推送镜像到dockerhub
- 制作filebeat镜像
- dockerfile
- 推送镜像到dockerhub
- example-application微服务的filebeat配置:
- filebeat.yml的参考配置:
- input.yml配置:
- 修改dockerfile
- 一键发布
- 启动之后
- message-dispatcher微服务的日志
- 查看日志索引
- logstash 详解
- stash第一个事件
- Logstash的核心流程的三个环节
- logstash数值类型
- logstash 条件判断
- logstash 比较运算符
- 数据输入环节
- stdin
- file
- syslogs
- beats
- kafka
- stash第一个事件
- 数据处理环节
- grok解析文本并构造
- date日期解析
- mutate字段转换
- covert类型转换
- split
- merge
- rename
- remove_field:移除字段
- join
- geoip
- ruby
- urldecode
- kv
- useragent
- 数据输出
- stdout
- file
- kafka
- elasticseach
- Kibana查看应用日志
- 1 查看应用日志
- 2 如何搜索日志
- 3 如何查看指定时间的应用日志
- 4 如何定位错误日志
- 5 如何展开显示日志
- es的安全认证
- 配置 elk的ElastAlert 预警插件
- ELK的关系
- Prometheus+Grafana 检测预警
- 什么是性能可观测
- 系统监控的核心指标
- 系统性能指标
- 资源性能指标
- 系统监控的核心指标
- 什么是prometheus
- prometheus的运行原理
- prometheus主要特点
- 什么是 Grafana
- Prometheus的体系结构
- Prometheus+Grafana分层架构
- Promcthcus体系涉及的组件
- 如何收集度量值
- 指标类型
- 计数器
- 仪表盘
- 直方图
- Summary
- 指标摘要及聚合
- 指标摘要
- 指标聚合
- 一键安装 prometheus
- bridge网络管理
- 创建库
- docker编排文件
- 一键安装 prometheus的脚本
- 进入 prometheus
- 进入 grafana
- Prometheus+Grafana监控SpringBoot项目JVM信息
- SpringBoot项目配置JVM采集
- Prometheus配置
- 配置grafana监控Linux系统
- 使用 Exporter 收集指标
- inux直接安装node_exporter
- 使用Docker容器安装node_exporter
- 创建一个任务定时扫描暴露的指标信息
- 创建仪表盘grafna
- 导入Dashboard
- 选择数据源为Prometheus
- 配置grafana监控SpringBoot应用
- 主要步骤
- 找jvm的 dashboard
- JVM Quarkus 面板
- Prometheus数据模型
- time-series 时间序列值
- Sample样本值
- metrics name指标名称
- label标签
- Notation(符号)
- TSDB时序数据库
- 度量指标类型
- Counter(计数器)类型
- Gauge(计量器、测量器)
- Histogram(柱状图、直方图)
- Summary
- Summary 和 Histogram 的区分
- 学习 PromQL
- 数据模型
- PromQL 入门
- HTTP API
- 告警和通知
- 配置告警规则
- 使用 Alertmanager 发送告警通知
- 服务发现
- 为什么需要服务发现
- prometheus目前支持的服务发现类型
- 基于文件的服务发现方式
- file_sd_configs
- 基于consul 的服务发现
- 什么是基于consul的服务发现
- Prometheus配置
- 基于eureka的服务发现
- eureka 客户端暴露出 prometheus 端口
- prometheus配置文件
- 基于nacos的服务发现
- docker 编排文件
- 生产的配置文件
- 修改prometheus配置文件
- 修改springboot项目配置文件
- 什么是性能可观测
- 全方位 Springcloud 性能调优
- Servlet 容器 优化
- Zuul配置 优化
- Feign 配置优化
- hystrix配置 优化
- ribbon 优化
- 高质量实操:SpringCloud 高并发实战案例
- 1、超高并发10Wqps秒杀实操
- 2、超高并发100Wqps车联网实操
- 3、N多其他的超高并发实操项目
- 技术自由的实现路径:
- 实现你的 架构自由:
- 实现你的 响应式 自由:
- 实现你的 spring cloud 自由:
- 实现你的 linux 自由:
- 实现你的 网络 自由:
- 实现你的 分布式锁 自由:
- 实现你的 王者组件 自由:
- 实现你的 面试题 自由:
- 参考文献
当前版本V1
此书会持续迭代,最新版本,请关注公众号:技术自由圈
一键导入 SpringCloud 开发环境 (地表最强)
SpringCloud + docker 学习环境非常复杂,尼恩搞这个 前前后后起码 折腾了一周 ,应该还不止,
其中,很多头疼的工作,包括linux内核升级、磁盘扩容等等, 苦不堪言。
现在把这个环境,以虚拟机box镜像的方式,导出来直接给大家,
大家一键导入后,直接享受SpringCloud + docker 的实操,可以说,爽到不要不要的。
以上软件和 尼恩个人的虚拟机box镜像,可以找尼恩获取。
环境准备
硬件总体要求,可以参考尼恩的本地硬件情况:
1 硬件要求。
本文硬件总体要求如下表:
序号 | 硬件 | 要求 |
---|---|---|
1 | CPU | 至少2核 |
2 | 内存 | 至少16G |
3 | 硬盘 | 至少100G磁盘空间 |
2 本地虚拟机环境
软件 | 版本 |
---|---|
Win | win10以上 |
virtual box | 6以上 |
vagrant | 2以上 |
一键导入OR自己折腾
大家一键导入尼恩的虚拟机环境,里边zookeeper、nacos、docker、k8s等组件都已经预装,直接享受SpringCloud + docker 的实操,可以说,爽到不要不要的。
当然,如果想自己折腾, 也可以按照的步骤来哈。
工欲善其事 必先利其器 |
---|
地表最强 开发环境: vagrant+java+springcloud+redis+zookeeper镜像下载(&制作详解) |
地表最强 热部署:java SpringBoot SpringCloud 热部署 热加载 热调试 |
地表最强 发请求工具(再见吧, PostMan ):IDEA HTTP Client(史上最全) |
地表最强 PPT 小工具: 屌炸天,像写代码一样写PPT |
无编程不创客,无编程不创客,一大波编程高手正在疯狂创客圈交流、学习中! 找组织,GO |
随书源码 crazy-springcloud 脚手架涉以及基础中间件
本PDF的随书源码仓库,就是尼恩的 《Java 高并发核心编程 卷3 加强版,老版本为 SpringCloud Nginx 高并发核心编程》一书的源码
也是尼恩的一个微服务开发脚手架 crazy-springcloud,其大致的模块和功能具体如下:
crazymaker-server -- 根项目
│ ├─cloud-center -- 微服务的基础设施中心
│ │ ├─cloud-eureka -- 注册中心
│ │ ├─cloud-config -- 配置中心
│ │ ├─cloud-zuul -- 网关服务
│ │ ├─cloud-zipkin -- 监控中心
│ ├─crazymaker-base -- 公共基础依赖模块
│ │ ├─base-common -- 普通的公共依赖,如 utils 类的公共方法
│ │ ├─base-redis -- 公共的 redis 操作模块
│ │ ├─base-zookeeper -- 公共的 zookeeper 操作模块
│ │ ├─base-session -- 分布式 session 模块
│ │ ├─base-auth -- 基于 JWT + SpringSecurity 的用户凭证与认证模块
│ │ ├─base-runtime -- 各 provider 的运行时公共依赖,装配的一些通用 Spring IOC Bean 实例
│ ├─crazymaker-uaa --业务模块: 用户认证与授权
│ │ ├─uaa-api -- 用户 DTO、Constants 等
│ │ ├─uaa-client -- 用户服务的 Feign 远程客户端
│ │ ├─uaa-provider -- 用户认证与权限的实现,包含controller 层、service层、dao层的代码实现
│ ├─crazymaker-seckill --业务模块: 秒杀练习
│ │ ├─seckill-api -- 秒杀 DTO、Constants 等
│ │ ├─seckill-client -- 秒杀服务的 Feign 远程调用模块
│ │ ├─seckill-provider -- 秒杀服务核心实现,包含controller层、service层、dao层的代码实现
│ ├─crazymaker-demo --业务模块: 练习演示
│ │ ├─demo-api -- 演示模块的 DTO、Constants 等
│ │ ├─demo-client -- 演示模块的 Feign 远程调用模块
│ │ ├─demo-provider -- 演示模块的核心实现,包含controller层、service层、dao层的代码实现
基于 crazy-springcloud 脚手架(其他的脚手架也类似)的微服务开发和自验证过程中,涉及到的基础中间件大致如下:
(1)ZooKeeper (虚拟机中已经预装)
ZooKeeper 是一个分布式的、开放源码的分布式协调应用程序,是大数据框架 Hadoop 和 Hbase的重要组件。在分布式应用中,它能够高可用地提供很多保障数据一致性的基础能力:分布式锁、选主、分布式命名服务等。
在 crazy-springcloud 脚手架中,高性能分布式 ID 生成器用到了 ZooKeeper。有关其原理和使用,请参见《Netty Zookeeper Redis 高并发实战》一书。
(2)Redis (虚拟机中已经预装)
Redis 是一个高性能的缓存数据库。在高并发的场景下,Redis 可以对关系数据库起到很好的缓冲作用;在提高系统的并发能力和响应速度方面,Redis 举足轻重和至关重要。crazy-springcloud 脚手架的分布式 Session 用到了 Redis。 有关 Redis 的原理和使用,还是请参见《Netty Zookeeper Redis 高并发实战》一书。
(3)Eureka (虚拟机中已经预装)
Eureka 是 Netflix 开发的服务注册和发现框架,本身是一个 REST 服务提供者,主要用于定位运行在 AWS(Amazon 云)的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务注册和发现功能。
(4)SpringCloud Config (虚拟机中已经预装)
SpringCloud Config 是 SpringCloud 全家桶中最早的配置中心,虽然在生产场景中,很多的企业已经使用 Nacos 或者 Consul 整合型的配置中心替代了独立的配置中心,但是 Config 依然适用于 SpringCloud 项目,通过简单的配置即可使用。
(5) Zuul
Zuul 是 Netflix 开源网关,可以和 Eureka、Ribbon、Hystrix 等组件配合使用,SpringCloud 对Zuul 进行了整合与增强,使用其作为微服务集群的内部网关,负责对给集群内部各个 provider 服务提供者进行 RPC 路由和请求过滤。
以上中间件的端口配置,以及部分安装和使用视频,大致如下表所示。
中间件 | 链接地址 |
---|---|
Linux Redis 安装(带视频) | Linux Redis 安装(带视频) |
Linux Zookeeper 安装(带视频) | Linux Zookeeper 安装, 带视频 |
…完整的开发环境的准备工作,-> | 请去疯狂创客圈 博客园 总入口 |
。。。。 |
ok,是不是很简单
源码请参见 《Java 高并发核心编程 卷3 加强版,老版本为 SpringCloud Nginx 高并发核心编程》一书源码
虽然SpringCloud 入门很简单,但是原理很复杂, 而且掌握SpringCloud 原理,是成为核心工厂师的必备知识
微服务 分布式系统的架构12次演进
在进入实操之前,咱们来点微服务 分布式系统的架构演进。
在尼恩的 《Java 高并发核心编程 卷3 加强版,老版本为 SpringCloud Nginx 高并发核心编程》 一书中,对亿级流量的系统架构,做了一个内部的分析。
本文《SpringCloud Alibaba学习圣经 》与之相配合,介绍一下微服务 分布式系统的架构演进。
《Java 高并发核心编程 卷3 加强版》的 亿级流量的系统架构, 大家更加要好好看看,可以结合起来看。
微服务 分布式系统的几个基础概念
在介绍架构之前,为了避免部分读者对架构设计中的一些概念不了解,下面对几个微服务分布式系统中最基础的概念进行介绍。
1)什么是分布式?
系统中的多个模块在不同服务器上部署,即可称为分布式系统,如Tomcat和数据库分别部署在不同的服务器上,或两个相同功能的Tomcat分别部署在不同服务器上。
2)什么是高可用?
系统中部分节点失效时,其他节点能够接替它继续提供服务,则可认为系统具有高可用性。
3)什么是集群?
一个特定领域的软件部署在多台服务器上并作为一个整体提供一类服务,这个整体称为集群。
如Zookeeper中的Master和Slave分别部署在多台服务器上,共同组成一个整体提供集中配置服务。
在常见的集群中,客户端往往能够连接任意一个节点获得服务,并且当集群中一个节点掉线时,其他节点往往能够自动的接替它继续提供服务,这时候说明集群具有高可用性。
4)什么是负载均衡?
请求发送到系统时,通过某些方式把请求均匀分发到多个节点上,使系统中每个节点能够均匀的处理请求负载,则可认为系统是负载均衡的。
5)什么是正向代理和反向代理?
系统内部要访问外部网络时,统一通过一个代理服务器把请求转发出去,在外部网络看来就是代理服务器发起的访问,此时代理服务器实现的是正向代理;
当外部请求进入系统时,代理服务器把该请求转发到系统中的某台服务器上,对外部请求来说,与之交互的只有代理服务器,此时代理服务器实现的是反向代理。
简单来说,正向代理是代理服务器代替系统内部来访问外部网络的过程,反向代理是外部请求访问系统时通过代理服务器转发到内部服务器的过程。
架构演进1:单机架构
在网站最初时,应用数量与用户数都较少,可以把Java应用(主要是Tomcat承载)和数据库部署在同一台服务器上。
浏览器往发起请求时,首先经过DNS服务器(域名系统)把域名转换为实际IP地址10.102.4.1,浏览器转而访问该IP对应的Tomcat。
具体的架构图,如下:
架构瓶颈:
随着用户数的增长,Tomcat和数据库之间竞争资源,单机性能不足以支撑业务。
架构演进2:引入缓存架构
随着 吞吐量的提升, 不得不引入引入缓存架构。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。
含: 本地缓存和分布式缓存
在Tomcat同服务器上或同JVM中增加本地缓存,并在外部增加分布式缓存,缓存热门商品信息或热门商品的html页面等。
涉及的技术包括:
使用caffeine 作为本地缓存,使用Redis作为分布式缓存
架构瓶颈:
(1)这里会涉及缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题
(2)这里会涉及缓存一致性的问题
(3)这里会涉及 hotkey的问题
有关上面问题的解决方案:
请参见尼恩的 《100Wqps三级缓存组件实操》+ 《100Wqps Caffeine 底层源码、架构实操实操》
架构演进3:接入层引入反向代理实现负载均衡
接下来,缓存抗住了大部分的访问请求,服务层Tomcat上还是吞吐量低,响应逐渐变慢,需要进行架构演进。
在多台服务器上分别部署Tomcat,使用反向代理软件(Nginx)把请求均匀分发到每个Tomcat中。
此处假设Tomcat最多支持100个并发,Nginx最多支持50000个并发,那么理论上Nginx把请求分发到500个Tomcat上,就能抗住50000个并发。
**其中涉及的技术包括:**Nginx、HAProxy,
两者都是工作在网络第七层的反向代理软件,主要支持http协议,还会涉及session共享、文件上传下载的问题。
架构演进4:数据库读写分离
反向代理使服务层的并发量大大增加,但并发量的增长也意味着: 更多请求会穿透到数据库,数据库最终成为瓶颈。
数据库如何高并发?
简单的方案:把数据库划分为读库和写库,读库可以有多个,
读库和写库之间,如何实现数据一致性?
简单的方案:可以通过DB的同步机制,把写库的数据同步到读库,对于需要查询最新写入数据场景,可通过在缓存中多写一份,通过缓存获得最新数据。
数据库读写分离的架构如下:
其中涉及的技术包括:shardingjdbc ,它是数据库中间件,可通过它来组织数据库的分离读写和分库分表,客户端通过它来访问下层数据库,还会涉及数据同步,数据一致性的问题。
有关上面分库分表解决方案:
请参见尼恩的 《10Wqps 日志平台实操》, 对分库分表方案,做了非常详解的架构介绍,并且在实操维度,对其中的核心的组件分布式ID,结合雪花id源码,百度id源码,shardingjdbc id源码,做了深入骨髓的介绍。
架构演进5:数据库按业务分库
业务逐渐变多,不同业务之间的访问量差距较大,不同业务直接竞争数据库,相互影响性能。
随着用户数的增长,单机的写库会逐渐会达到性能瓶颈。
把不同业务的数据保存到不同的数据库中,使业务之间的资源竞争降低,对于访问量大的业务,可以部署更多的服务器来支撑。
有关上面分库分表解决方案:
请参见尼恩的 《10Wqps 日志平台实操》, 对分库分表方案,做了非常详解的架构介绍,并且在实操维度,对其中的核心的组件分布式ID,结合雪花id源码,百度id源码,shardingjdbc id源码,做了深入骨髓的介绍。
架构演进6:使用LVS或F5接入层负载均衡
随着吞吐量大于5W,接入层Nginx扛不住了
由于瓶颈在Nginx,因此无法LVS或F5来实现多个Nginx的负载均衡。
图中的LVS和F5是工作在网络第四层的负载均衡解决方案,区别是:
(1 ) LVS是软件,运行在操作系统内核态,可对TCP请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于Nginx,可假设单机的LVS可支持几十万个并发的请求转发;
(2 ) F5是一种负载均衡硬件,与LVS提供的能力类似,性能比LVS更高,但价格昂贵。
如果不是财大气粗的guoqi,推荐使用LVS。
由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。
LVS 如何高可用呢?
可使用keepalived软件模拟出虚拟IP,然后把虚拟IP绑定到多台LVS服务器上,浏览器访问虚拟IP时,会被路由器重定向到真实的LVS服务器
当主LVS服务器宕机时,keepalived软件会自动更新路由器中的路由表,把虚拟IP重定向到另外一台正常的LVS服务器,从而达到LVS服务器高可用的效果。
架构演进7:通过DNS轮询实现机房间的负载均衡
由于LVS也是单机的,随着并发数增长到几十万时,LVS服务器最终会达到瓶颈,此时用户数达到千万甚至上亿级别,用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同。
此时,可以使用 DNS 进行负载均衡:在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。
当用户访问taobao时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。
此方式能实现机房间的负载均衡
至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题。
问题是,光用DNS进行简单的 LVS负载均衡,是不够的。
所以呢?大部分的大厂应用,都是采用 智能DNS + 接入层流量二次路由的模式, 具体的案例,可以来找尼恩进行交流,这里不做展开。主要是内容太多啦。
架构演进8:引入NoSQL数据库和搜索引擎等技术
随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单单依靠数据库无法解决如此丰富的需求。
当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景。
对于统计报表场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢
对于全文检索、可变数据结构等场景,数据库天生不适用,使用 elasticsearch 分布式搜索引擎解决。
如对于海量文件存储,可通过分布式文件系统hbase解决
对于全文检索场景,可通过搜索引擎如ElasticSearch解决,对于多维分析场景,可通过Kylin或Druid等方案解决。
当然,引入更多组件同时会提高系统的复杂度,不同的组件保存的数据需要同步,需要考虑一致性的问题,需要有更多的运维手段来管理这些组件等。
接下来尼恩会讲 云原生+大数据的架构,就是介绍的这套方案。
架构演进9:大应用拆分为微服务
引入更多组件解决了丰富的需求,业务维度能够极大扩充,随之而来的是一个应用中包含了太多的业务代码,业务的升级迭代、部署维护变得困难,效率低下。
解决方式是,进行 业务的解耦。按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。
不同的业务,可以解耦成不同的微服务。
这样的服务就是所谓的微服务,应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。
此外,可以通过Dubbo、SpringCloud等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。
这时候应用之间可能会涉及到一些公共配置,可以通过分布式配置中心 Nacos来解决。
架构演进10:引入企业服务总线ESB对微服务进行编排
由于不同服务之间存在共用的模块,由微服务单独管理会导致相同代码存在多份,导致公共功能升级时全部应用代码都要跟着升级。
不同微服务的接口访问方式不同,微服务代码需要适配多种访问方式才能使用,此外,微服务访问微服务,微服务之间也可能相互访问,调用链将会变得非常复杂,逻辑变得混乱。
在微服务的基础上,以应用为单位,进行微服务的分组,并且引入企业服务总线ESB,对微服务进行编排,形成应用。
通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来相互调用,以此降低系统的耦合程度。
这种微服务编排为多个应用,公共服务单独抽取出来来管理,并使用企业消息总线来解除服务之间耦合问题的架构。
接下来尼恩会讲 ESB架构,就是介绍的这套方案。
架构演进11:引入容器化技术实现动态扩容和缩容
业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题
此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境,部署服务等,运维将变得十分困难。
目前最流行的容器化技术是Docker,最流行的容器管理服务是Kubernetes(K8S),应用/服务可以打包为Docker镜像,通过K8S来动态分发和部署镜像。
Docker镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。
把整个“操作系统”打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动Docker镜像就可以把服务起起来,使服务的部署和运维变得简单。
有关 Docker + Kubernetes(K8S) 的内容,请参见尼恩的电子书:
由于内容确实太多, 所以写多个pdf 电子书:
(1) 《 Docker 学习圣经 》PDF
(2) **《 SpringCloud Alibaba 微服务 学习圣经 》**PDF
使用 Docker + Kubernetes(K8S) 后,在大促的之前,可以在现有的机器集群上划分出服务器来启动Docker镜像,增强服务的性能
大促过后就可以关闭镜像,对机器上的其他服务不造成影响。
架构演进12:以云平台承载系统
使用容器化技术后服务动态扩缩容问题得以解决,但是机器还是需要公司自身来管理,在非大促的时候,还是需要闲置着大量的机器资源来应对大促,机器自身成本和运维成本都极高,资源利用率低。
系统可部署到公有云上,利用公有云的海量机器资源,解决动态硬件资源的问题
在大促的时间段里,在云平台中临时申请更多的资源,结合Docker和K8S来快速部署服务,在大促结束后释放资源,真正做到按需付费,资源利用率大大提高,同时大大降低了运维成本。
所谓的云平台,就是把海量机器资源,通过统一的资源管理,抽象为一个资源整体
在云平台上可按需动态申请硬件资源(如CPU、内存、网络等),并且之上提供通用的操作系统,提供常用的技术组件(如Hadoop技术栈,MPP数据库等)供用户使用,甚至提供开发好的应用
用户不需要关心应用内部使用了什么技术,就能够解决需求(如音视频转码服务、邮件服务、个人博客等)。
在云平台中会涉及如下几个概念:
IaaS:基础设施即服务。对应于上面所说的机器资源统一为资源整体,可动态申请硬件资源的层面;
PaaS:平台即服务。对应于上面所说的提供常用的技术组件方便系统的开发和维护;
SaaS:软件即服务。对应于上面所说的提供开发好的应用或服务,按功能或性能要求付费。
至此:以上所提到的从高并发访问问题,到服务的架构和系统实施的层面都有了各自的解决方案。
架构演进的涉及的核心知识
通过以上架构的演进,可以看出:
(1)开发侧: 重点的知识体系是 SpringCloud + Nginx 的基础架构;
有关 SpringCloud + Nginx的知识,请阅读本文《SpringCloud Alibaba学习圣经 》和与之相配合的《Java 高并发核心编程 卷3 加强版》
《Java 高并发核心编程 卷3 加强版》
(2)运维侧: 重点的知识体系是 docker + k8s 的基础架构;
有关 docker + k8s 的知识,请阅读本文《docker 学习圣经 》和与之相配合的《K8s 学习圣经》
搞定这些,应对亿级流量,就具备了基础的知识底座。
本文,聚焦 SpringCloud 的学习,主要是 SpringCloud Alibaba 的学习。
SpringCloud netflix 入门
要了解 SpringCloud Alibaba ,先得了解 SpringCloud netflix。
为啥? SpringCloud Alibaba 仅仅是在 SpringCloud netflix 的基础上,替换了部分组件。 比如说注册中心,比如RPC组件。
所以,咱们得从SpringCloud netflix 开始。
SpringCloud Netflix全家桶是 Pivotal 团队提供的一整套微服务开源解决方案,包括服务注册与发现、配置中心、全链路监控、服务网关、负载均衡、断路器等组件,以上的组件主要通过对 NetFilx的 NetFlix OSS 套件中的组件通过整合完成的,其中,比较重要的整合组件有:
(1)spring-cloud-netflix-Eureka 注册中心
(2)spring-cloud-netflix-hystrix RPC保护组件
(3)spring-cloud-netflix-ribbon 客户端负载均衡组件
(4)spring-cloud-netflix-zuul 内部网关组件
(6)spring-cloud-config 配置中心
SpringCloud 全家桶技术栈除了对 NetFlix OSS的开源组件做整合之外,还有整合了一些选型中立的开源组件。比如,SpringCloud Zookeeper 组件整合了 Zookeeper,提供了另一种方式的服务发现和配置管理。
SpringCloud 架构中的单体业务服务是基于 SpringBoot 应用进行启动和执行的。SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。SpringCloud 利用 SpringBoot 是什么关系呢?
(1)首先 SpringCloud 利用 SpringBoot 开发便利性巧妙地简化了分布式系统基础设施的开发;
(2)其次 SpringBoot 专注于快速方便地开发单体微服务提供者,而 SpringCloud 解决的是各微服务提供者之间的协调治理关系;
(3)第三 SpringBoot 可以离开 SpringCloud 独立使用开发项目,但是 SpringCloud 离不开SpringBoot,其依赖 SpringBoot 而存在。
最终,SpringCloud 将 SpringBoot 开发的一个个单体微服务整合并管理起来,为各单体微服务提供配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等基础的分布式协助能力。
SpringCloud 开发脚手架
无论是单体应用还是分布式应用,如果从零开始开发,都会涉及很多基础性的、重复性的工作需要做,比如用户认证,比如 session 管理等等。有了开发脚手架,这块基础工作就可以省去,直接利用脚手架提供的基础模块,然后按照脚手架的规范进行业务模块的开发即可。
笔者看了开源平台的不少开源的脚手架,发现很少是可以直接拿来做业务模块开发的,或者封装的过于重量级而不好解耦,或者业务模块分包不清晰而不方便开发,所以,本着简洁和清晰的原则,笔者的发起的疯狂创客圈社群推出了自己的微服务开发脚手架 crazy-springcloud,其大致的模块和功能具体如下:
crazymaker-server -- 根项目
│ ├─cloud-center -- 微服务的基础设施中心
│ │ ├─cloud-eureka -- 注册中心
│ │ ├─cloud-config -- 配置中心
│ │ ├─cloud-zuul -- 网关服务
│ │ ├─cloud-zipkin -- 监控中心
│ ├─crazymaker-base -- 公共基础依赖模块
│ │ ├─base-common -- 普通的公共依赖,如 utils 类的公共方法
│ │ ├─base-redis -- 公共的 redis 操作模块
│ │ ├─base-zookeeper -- 公共的 zookeeper 操作模块
│ │ ├─base-session -- 分布式 session 模块
│ │ ├─base-auth -- 基于 JWT + SpringSecurity 的用户凭证与认证模块
│ │ ├─base-runtime -- 各 provider 的运行时公共依赖,装配的一些通用 Spring IOC Bean 实例
│ ├─crazymaker-uaa --业务模块: 用户认证与授权
│ │ ├─uaa-api -- 用户 DTO、Constants 等
│ │ ├─uaa-client -- 用户服务的 Feign 远程客户端
│ │ ├─uaa-provider -- 用户认证与权限的实现,包含controller 层、service层、dao层的代码实现
│ ├─crazymaker-seckill --业务模块: 秒杀练习
│ │ ├─seckill-api -- 秒杀 DTO、Constants 等
│ │ ├─seckill-client -- 秒杀服务的 Feign 远程调用模块
│ │ ├─seckill-provider -- 秒杀服务核心实现,包含controller层、service层、dao层的代码实现
│ ├─crazymaker-demo --业务模块: 练习演示
│ │ ├─demo-api -- 演示模块的 DTO、Constants 等
│ │ ├─demo-client -- 演示模块的 Feign 远程调用模块
│ │ ├─demo-provider -- 演示模块的核心实现,包含controller层、service层、dao层的代码实现
在业务模块如何分包的问题上,实际上大部分企业都有自己的统一规范。crazy-springcloud 脚手架从职责清晰、方便维护、能快速导航代码的角度出发,将每一个业务模块,细分成以下三个子模块:
(1) module-api
此子模块定义了一些公共的 Constants 业务常量和 DTO 传输对象,该子模块既被业务模块内部依赖,也可能被依赖该业务模块的外部模块所依赖;
(2) module-client
此子模块定义了一些被外部模块所依赖的 Feign 远程调用客户类,该子模块是专供外部的模块,不能被内部的其他子模块所依赖;
(3) module-provider
此子模块是整个业务模块的核心,也是一个能够独立启动、运行的服务提供者(Application),该模块包含涉及到业务逻辑的 controller 层、service 层、dao 层的完整代码实现。
crazy-springcloud 微服务开发脚手架在以下两方面进行了弱化:
(1)在部署方面对容器的介绍进行了弱化,没有使用 Docker 容器而是使用 Shell 脚本。有多方面的原因:一是本脚手架初心是学习,使用 Shell 脚本而不是 Docker 去部署,方便大家学习 Shell 命令和脚本;二是 Java 和 Docker 其实整合得很好,学习非常容易,可以稍加配置就能做到一键发布,找点资料就可以掌握; 三是部署和运维是一个专门的工作,生产环境的部署、甚至是整个自动化构建和部署的工作,实际上属于运维的专项工作,由专门的运维岗位人员去完成,而部署的核心仍然是 Shell 脚本,所以对于开发人员来说掌握 Shell 脚本才是重中之重。
(2)对监控软件的介绍进行了弱化。本书没有对链路监控、JVM性能指标、断路器监控软件的使用做专门介绍。有多方面的原因:一是监控的软件太多,如果介绍太全,篇幅又不够,介绍太少,大家又不一定用到; 二是监控软件的使用大多是一些软件的操作步骤和说明,原理性的内容比较少,使用视频的形式会比文字形式知识传递的效果会更好。疯狂创客圈后续可能(但不一定)会推出一些微服务监控方面的教学视频供大家参考,请大家关注社群博客。不论如何,只要掌握了 SpringCloud 核心原理,对那些监控组件使用的掌握,对大家来说基本上都是一碟小菜。
启动Eureka Server 注册中心
Eureka 本身是 Netflix 开源的一款注册中心产品,并且 SpringCloud 提供了相应的集成封装,选择其作为注册中心的讲解实例,是出于以下的原因:
(1)Eureka 在业界的应用十分广泛(尤其是国外),整个框架也经受住了 Netflix 严酷生产环境的考验。
(2)除了 Eureka 注册中心,Netflix 的其他服务治理功能也十分强大,包括 Ribbon、Hystrix、Feign、Zuul 等组件,结合到一起组成了一套完整的服务治理框架,使得服务的调用、路由也变得异常容易。
那么,Netflix 和 SpringCloud 是什么关系呢?
Netflix 是一家互联网流媒体播放商,是美国视频巨头,访问量非常的大。也正是如此,Netflix 把整体的系统迁移到了微服务架构。并且,Netflix 就把它的几乎整个微服务治理生态中的组件,都开源贡献给了 Java 社区,叫做 Netflix OSS。
SpringCloud 是 Spring 背后的 Pivotal 公司(由 EMC 和 VMware 联合成立的公司)在 2015 年推出的开源产品,主要对 Netflix 开源组件的进一步封装,方便 Spring 开发人员构建微服务架构的应用。
SpringCloud Eureka 是 SpringCloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责完成微服务实例的自动化注册与发现,这也是微服务架构中最为核心和基础的功能。
Eureka 所治理的每一个微服务实例,被称之为 Provider Instance (提供者实例)。每一个 Provider Instance 微服务实例包含一个 Eureka Client 客户端组件(相当于注册中心客户端组件)
以上是关于K8S圣经12:SpringCloud+Jenkins+ K8s Ingress 自动化灰度发布的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud Alibaba 学习圣经,10万字实现 SpringCloud 自由
K8S学习圣经:大白话说K8S底层原理,14W字实现K8S自由
微服务圣经1:零基础搭建一套SpringCloud微服务脚手架(SpringCloud+Dubbo+Docker+Jenkins)