第6章 SpringCLoud 模拟京东在线购物
第6章-SpringCLoud-模拟京东在线购物
本章所讲内容:
6.1 基于 Springcloud 开发的电商平台微服务架构解读
6.2 单体架构 vs 微服务架构对比分析
6.3 SpringCloud 基本介绍
6.4 部署 Springcloud 开发的电商平台到 k8s 集群:部署 eureka 服务
实验环境:k8s 集群:
k8s 的控制节点
ip:192.168.20.201 ; 主机名:k8s-master01 ; 配置:4vCPU/4Gi 内存
ip:192.168.20.202 ; 主机名:k8s-master02 ; 配置:4vCPU/4Gi 内存
ip:192.168.20.203 ; 主机名:k8s-master03 ; 配置:4vCPU/4Gi 内存
k8s 的工作节点:
ip:192.168.20.204 ; 主机名:k8s-node01; 配置:4vCPU/8Gi 内存
ip:192.168.20.205 ; 主机名:k8s-node02; 配置:4vCPU/8Gi 内存
harbor 机器:
ip:192.168.20.206 ; 主机名:harbor ; 配置:4vCPU/2Gi 内存
Mysql 服务:mysql 部署在 k8s-master01 上,暴露的端口是 3306
下面实验依赖的服务有 harbor、Ingress controller、mysql,上一节课已经安装成功了注:为什么要将 SpringCloud 项目迁移到 K8S 平台?
SpringCloud 很多功能都跟kubernetes 重合,比如服务发现,负载均衡,配置管理,所以如果把
SpringCloud 部署到k8s,那么很多功能可以直接使用 k8s 原生的,减少复杂度。
6.1 基于 Springcloud 开发的电商平台微服务架构解读
6.1.1 基于 springcloud 的电商平台功能图
画图工具: Xmind Visio
6.1.2 基于 springcloud 的电商平台架构图
6.2 单体架构vs 微服务架构对比分析
什么是单体架构?
所有的服务放到一个代码块里开发,如果是 java 开发的代码,启动一个 jar 文件之后,所有功能都自动实现了。耦合性太高了,更新一个功能,整个代码都需要重新部署。
优点:部署方便
缺点:升级的时候只改动一个功能,可能会影响所有的服务
什么是微服务架构?
把一个大的平台,拆分成很多小的功能模块,每个模块单独开发,单独部署。优点:维护的时候,改动一个功能模块,不会影响其他的功能模块
缺点:服务太多,需要人员维护
6.3 SpringCloud 基本介绍
6.3.1 SpringCloud 是什么? 官方解释:
官网: https://spring.io/projects/spring-cloud/
SpringCloud 是一系列框架的有序集合。它利用 SpringBoot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot 的开发风格做到一键启动和部署。SpringCloud 并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 SpringBoot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
6.3.2 SpringCloud 优缺点
1) SpringCloud 来源于 Spring,质量、稳定性、持续性都可以得到保证。
SpirngCloud 以 SpringBoot 为基础开发框架,可以给开发者大量的微服务开发经验,例如,只要极少量的标签,你就可以创建一个配置服务器,再加一些标签,你就可以得到一个客户端库来配置你的服务,更加便于业务落地。
2) SpringCloud 是 Java 领域最适合做微服务的框架,对 Java 开发者来说就很容易开发。
3) 耦合度低,不影响其他模块
4) 多个开发团队可以并行开发项目,提高开发效率
5) 直接写自己的代码即可,然后暴露接口,通过组件进行服务通信。
缺点:
只能针对 Java 开发部署麻烦、组件多
6.3.3 为何要将 SpringCloud 项目部署到 k8s 平台?
k8s 是一个容器编排工具,能跑任何代码,k8s 本身的功能也很多:
自动扩缩容、能跑任何代码、服务发现和负载均衡、配置管理中心、k8s 结合 istio 可以实现熔断、超时、重试这些功能。
springcloud 开发的代码部署到 k8s 里,那 springcloud 自带的很多功能可以直接用 k8s 取实现, 如 springcloud 有eureka:服务注册和发现,可以用 k8s 的 coredns 和 service,springcloud 里的网段服务 Springcloud Gateway 可以用 k8s 的 ingress-nginx-controller 去实现,spirngcloud config 可以用 K8s 的 configmap 或者 secret 实现,springcloud 里的 hystrix(熔断)可以基于Istio 实现。
6.3.4 将公司业务部署到 k8s 的完整流程
第一步:写代码、开发人员要基于 Springcloud 框架开发代码,基于 Springcloud 开发的代是微服务架构。
第二步:获取代码(可以从代码仓库获取开发写好的代码,代码可以是 gitlab 或者 svn 都可以) 第三步:编译代码,如果是 Springcloud 开发的 java 代码,mvn 命令去编译
第四步:基于 dockerfile 制作镜像,把代码和依赖的服务封装到镜像里第五步:把做好的镜像传到私有镜像仓库,私有镜像仓库用 harbor
第六步:创建 pod(选择一个合适的控制器管理 Pod,如 deployment 或者 Statefulset)
什么样的服务用 Deployment 管理 pod?
无状态的服务用 Deployment,那么问题来了,什么样的服务叫做无状态?
1、坏一个服务,对整体没影响,如 tomcat
2、不需要做会话保持
什么样的服务用 Statefulset 管理 pod?
有状态的服务用 Statefulset,有状态服务特点?
1、坏一个服务,对整体有影响,mysql 主从
2、需要做会话保持:statefulset 创建的 pod 有序的
3、需要做共享数据
第七步:在 Pod 前端创建一个 Service 资源,实现四层代理
第八步:如果是一个前端服务,映射到公网上的,比方说电商网站首页,需要搞成 https 安全加密的方式访问,那就需要基于 Ingress-nginx-controller 实现七层代理。
第九步:需要对 pod 里面的服务进行数据持久化(比方说 mysql、oracle、elasticsearch 等服务,需要存数据的),如何存数据?可以用分布式的存储:ceph、云存储。
第十步:需要把监控系统(Promethues+Grafana+Alertmanager 或者zabbix)搭建出来、需要把日志平台搭建出来(EFK、EFK+logstash+kafka/redis)
引申一个面试题:
上线一个新项目,需要多少 k8s 节点?
首先要看看在 K8s 里运行的服务大概有哪些,比方说运行的服务有 A、B、C A 服务需要部署两个,2 个 pod:10g、10VCPU
B 服务需要部署 10 个:10 个 Pod:20g、20VCPU C 服务需要部署 6 个:6 个 pod:12g、12VCPU
具体每个服务部署几个 pod,我们要压测,由运营或者项目经理去评估大概业务量,根据压测的结果:比方说请求量是一百万,我们需要使用 4g 内存、4vCPU,那有了这个数据,每个服务数量就可以大概确定。
A、B、C 三个服务运行的 pod 一共是占用 42g 内存、42VCPU,所有的 pod 总的内存和 cpu 都有了,那 k8s 节点配置就大概有数了。
控制节点至少 3 个做高可用:每个节点 8G 内存、12VCPU 工作节点 2 个: 每个节点 26g、26VCPU
6.4 部署 Springcloud 开发的电商平台到 k8s 集群:部署
eureka 服务
以下步骤均在 k8s 的控制节点xuegod63 上操作
6.4.1 SpringCloud 的微服务电商框架
6.4.2 安装 openjdk 和maven
在 k8s 控制节点 k8s-master01上操作
6.4.3 上传微服务源码包到 k8s 的控制节点 上
#解压
[root@k8s-master01 springcloud]# unzip microservic-test.zip
[root@k8s-master01 springcloud]# cd microservic-test
6.4.4 修改源代码,更改数据库连接地址在 k8s 控制节点 上操作
1) 修改库存服务 stock 的数据库连接地址
[root@k8s-master01 springcloud]# vim microservic-test/stock-service/stock-service-biz/src/main/resources/application-fat.yml
[root@k8s-master01 springcloud]# cat microservic-test/stock-service/stock-service-biz/src/main/resources/application-fat.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.201:3306/tb_stock?characterEncoding=utf-8
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.ms:8888/eureka,http://eureka-1.eureka.ms:8888/eureka,http://eureka-2.eureka.ms:8888/eureka
改成如下:
2) 修改产品服务 product 的数据库连接地址
[root@k8s-master01 springcloud]# vim microservic-test/product-service/product-service-biz/src/main/resources/application-fat.yml
[root@k8s-master01 springcloud]# cat microservic-test/product-service/product-service-biz/src/main/resources/application-fat.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.201:3306/tb_product?characterEncoding=utf-8
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.ms:8888/eureka,http://eureka-1.eureka.ms:8888/eureka,http://eureka-2.eureka.ms:8888/eureka
改成如下:
3) 修改订单数据库
[root@k8s-master01 springcloud]# vim microservic-test/order-service/order-service-biz/src/main/resources/application-fat.yml
[root@k8s-master01 springcloud]# cat microservic-test/order-service/order-service-biz/src/main/resources/application-fat.yml
spring:
datasource:
url: jdbc:mysql://192.168.20.201:3306/tb_order?characterEncoding=utf-8
username: root
password: 111111
driver-class-name: com.mysql.jdbc.Driver
eureka:
instance:
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.ms:8888/eureka,http://eureka-1.eureka.ms:8888/eureka,http://eureka-2.eureka.ms:8888/eureka
改成如下:
6.4.5 通过 Maven 编译、构建、打包源代码在 k8s 控制节点 上操作
修改源代码数据库的地址之后回到/root/springcloud/microservic-test 目录下执行如下命令:
编译完成大概需要 15-20 分钟,看到如下说明编译打包已经成功了:
[INFO] gateway-service ................................... SUCCESS [5:52.813s]
[INFO] eureka-service .................................... SUCCESS [1:19.355s]
[INFO] product-service ................................... SUCCESS [0.000s]
[INFO] product-service-api ............................... SUCCESS [0.152s]
[INFO] stock-service ..................................... SUCCESS [0.001s]
[INFO] stock-service-api ................................. SUCCESS [0.151s]
[INFO] product-service-biz ............................... SUCCESS [5.176s]
[INFO] stock-service-biz ................................. SUCCESS [0.183s]
[INFO] order-service ..................................... SUCCESS [0.000s]
[INFO] order-service-api ................................. SUCCESS [0.133s]
[INFO] order-service-biz ................................. SUCCESS [0.203s]
[INFO] basic-common-bom .................................. SUCCESS [0.001s]
[INFO] portal-service .................................... SUCCESS [0.567s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10:29.437s
[INFO] Finished at: Tue Aug 29 17:49:35 CST 2023
[INFO] Final Memory: 73M/551M
[INFO] ------------------------------------------------------------------------
6.4.6 在 k8s 中部署 Eureka 组件
修改 所有 上的 docker 的配置文件:
$ cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries":["192.168.20.206","harbor"]
}
EOF
注意:
daemon.json 中新增加了如下一行内容:
这样才可以使用 harbor 私有镜像仓库
重启 docker 使配置生效
登录 harbor
$ docker login 192.168.20.206
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
在 k8s 的控制节点 xuegod63 上操作创建拉取私有镜像仓库需要的 secret
[root@k8s-master01 microservic-test]# kubectl create ns ms && kubectl create secret docker-registry registry-pull-secret --docker-server=192.168.20.206 --docker-username=admin --docker-password=Harbor12345 -n ms
在 harbor 上创建一个项目 microservice
1) 构建镜像
上传基础镜像到控制节点
[root@k8s-master01 eureka-service]# pwd
/root/springcloud/microservic-test/eureka-service
[root@k8s-master01 eureka-service]# docker build -t 192.168.20.206/microservice/eureka:v1 .
[root@k8s-master01 eureka-service]# docker push 192.168.20.206/microservice/eureka:v1
2) 部署服务
修改 eureka.yaml 文件,把镜像变成 image: 192.168.1.62/microservice/eureka:v1
[root@k8s-master01 microservic-test]# cat k8s/eureka.yaml |egrep "image|ingressClassName"
ingressClassName: nginx
imagePullSecrets:
image: 192.168.20.206/microservice/eureka:v1
3) 更新 yaml 文件
4)查看 pod 状态
[root@k8s-master01 eureka-service]# kubectl get pod -n ms |grep eureka
eureka-0 1/1 Running 0 3m12s
eureka-1 1/1 Running 0 116s
eureka-2 1/1 Running 0 49s
上面运行没问题之后,找到自己电脑的 hosts 文件,新加如下一行:
在浏览器访问 eureka.ctnrs.com 即可,可看到如下,说明 eureka 部署成功了:
注意:
要想访问域名 eureka.ctnrs.com,
这个需要在自己电脑的 hosts 文件新增加如下内容,192.168.20.204 是 ingress-nginx-controller
这个 pod 的 ip 地址。
总结:
6.1 基于 Springcloud 开发的电商平台微服务架构解读
6.2 单体架构 vs 微服务架构对比分析
6.3 SpringCloud 基本介绍
6.4 部署 Springcloud 开发的电商平台到 k8s 集群:部署 eureka 服务





