SpringCloud微服务学习笔记(一)【介绍,Eureka,Ribbon,Nacos】
SpringCloud微服务学习笔记(一)【介绍,Eureka,Ribbon,Nacos】
何平安推荐去我的博客园看,因为一些原因不能远程调用它的图片地址:http://cnblogs.com/hepingan
微服务介绍
用于开发大型项目时,将所有代码都放在一个项目中会增加压力,而且单体架构的并发数也有限,占用的线程多的时候就不行了。这时就需要用到微服务分布式开发。
单体架构(monolithic structure):顾名思义,整个项目中所有功能模块都在一个工程中开发;项目部署时需要对所有模块一起编译、打包;项目的架构设计、开发模式都非常简单,当项目规模较小时,这种模式上手快,部署、运维也都很方便,因此早期很多小型项目都采用这种模式。
但随着项目的业务规模越来越大,团队开发人员也不断增加,单体架构就呈现出越来越多的问题:
- 团队协作成本高:试想一下,你们团队数十个人同时协作开发同一个项目,由于所有模块都在一个项目中,不同模块的代码之间物理边界越来越模糊。最终要把功能合并到一个分支,你绝对会陷入到解决冲突的泥潭之中。
- 系统发布效率低:任何模块变更都需要发布整个系统,而系统发布过程中需要多个模块之间制约较多,需要对比各种文件,任何一处出现问题都会导致发布失败,往往一次发布需要数十分钟甚至数小时。
- 系统可用性差:单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用。
微服务架构,首先是服务化,就是将单体架构中的功能模块从单体应用中拆分出来,独立部署为多个服务。同时要满足下面的一些特点:
- 单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。
- 团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人(2张披萨能喂饱)
- 服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响
SpringCloud依托于SpringBoot的自动装配能力,大大降低了其项目搭建、组件使用的成本。对于没有自研微服务组件能力的中小型企业,使用SpringCloud全家桶来实现微服务开发可以说是最合适的选择了! Spring Cloud
目前SpringCloud最新版本为2022.0.x
版本,对应的SpringBoot版本为3.x
版本,但它们全部依赖于JDK17,目前在企业中使用相对较少。
SpringCloud版本 | SpringBoot版本 |
---|---|
2022.0.x aka Kilburn | 3.0.x |
2021.0.x aka Jubilee | 2.6.x, 2.7.x (Starting with 2021.0.3) |
2020.0.x aka Ilford | 2.4.x, 2.5.x (Starting with 2020.0.3) |
Hoxton | 2.2.x, 2.3.x (Starting with SR5) |
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
因此,我们推荐使用次新版本:Spring Cloud 2021.0.x以及Spring Boot 2.7.x版本。JDK为11
微服务的一些模块:
本项目的源文件使用的是黑马程序员的2021版SpringCloud微服务教程的资料!!!springcloud版本为Hoxton,springboot版本为2.3.9
一个查看自己项目springboot和spring版本的测试类:
1 | public class App { |
服务拆分
原则:
跨模块的查询不同数据库的例子:
通过在order里查询orderid返回order的数据,其中包括user的数据,然而user-server的数据库和模块都是与order-server单独分开的,这时就需要用到RestTemplate和它的getForObject方法了。
OrderApplication:
1 | /** |
OderService:
1 | public Order queryOrderById(Long orderId) { |
Eureka
Eureka与消费者和提供者的关系
Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:
- Eureka Server:Eureka 服务注册中心,主要用于提供服务注册功能。当微服务启动时,会将自己的服务注册到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到 Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到。
- Eureka Client:Eureka 客户端,通常指的是微服务系统中各个微服务,主要用于和 Eureka Server 进行交互。在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,Eureka Server 将它从可用服务列表中移除(默认 90 秒),这就确保了调用服务的稳定安全性,确认那个server服务没有死。
搭建Eureka服务
新建一个Maven项目模块(eureka-server),在pom文件里添加eureka服务端的坐标:
1 | <dependency> |
再在main里面创建一个启动类,启动类上加上@EnableEurekaServer和@SpringBootApplication注解:
1 |
|
添加application.yml配置文件:
1 | server: |
这时启动eureka启动类,在浏览器输入localhost:10086展示出spring Eureka的网站搭建成功
Eureka注册中心
在user-service和order-service项目模块里的pom里添加client的坐标:
1 | <dependency> |
user-service和order-service里的application.yml添加配置:
1 | spring: |
再复制一个UserApplication,在修改选项里找到添加VM选项,输入-Dserver.port=8082,意思就是把它的端口号设置为8082,这是IDEA的高级功能。
这时Spring Eureka的网站上实例的UserService的数量就变成2了:
服务发现
直接在RestTemplate上添加@LoadBalanced注解
Ribbon
原理
使用
方法一:针对order服务的全部
在OrderApplication里添加负载均衡的方法:
1 |
|
这时再去多次访问查询功能,可以发现UserApplication的两个实例都有被访问的日志。
方法二:针对特定服务
在application.yml里添加:
1 | userservice: |
饥饿加载
Ribbon的默认为懒加载,第一次加载后会存在内存中,之后再加载就不用加载了。而饥饿加载会在项目启动时就加载了,第一次访问都不用加载了。
在application.yml里添加
1 | ribbon: |
Nacos
安装和入门
Eureka的升级版,而且还是阿里巴巴的产品,支持国产~github上可以下载,黑马的资料里也有,我选用的版本是2.2.3
nacos会占用8848端口(当然也可以修改)
进入bin目录,然后执行命令即可:
1 | startup.cmd -m standalone |
在浏览器输入地址:http://127.0.0.1:8848/nacos即可,默认的账号和密码都是nacos
更详细的教程参考:Nacos 安装教程(史上最详细保姆级教程)_nacos安装-CSDN博客
父工程的pom里引入nacos:
1 | <dependency> |
客户端(user-server和order-server)引入客户端依赖,并去掉原来的eureka依赖
1 | <!-- nacos客户端依赖包 --> |
修改application.yml:将原来的eureka配置注释掉,再在spring:下添加配置:
1 | cloud: |
修改完后记得重新编译运行下pom.xml,然后再启动项目,进入localhost:8848:
服务集群,Nacos负载均衡和环境隔离
通常一个服务端口断了都是先在本地替换另一个服务,而不是去其他ip调用服务,这时就需要使用集群来区别不同的地域IP了。添加服务集群属性:
在nacos:下添加:
discovery:
cluster-name: SH
这时这个项目集群就属于SH了。
有了集群就可以修改负载均衡了,我要想order的集群向user对应的集群优先请求(比如我的order配置的集群为重庆,那我发送的请求就优先从重庆集群的user中获取)。将order/application.yml原来的ribbon配置修改为:
1 | NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则 |
根据权重负载均衡,有些性能好的端口服务就可以多承担几次请求,差的就少一些,这时就需要设置权重了。在Nacos控制台里服务实例里的详细找到一个端口服务的编辑,里面可以修改权重:
环境隔离,就是隔离不同版本和服务的东西,设计中可以用可以不用。先新建一个命名空间,(Nacos默认会生成一个public的命名空间):
然后再在order的application.yml里配置命名空间ID:
1 | spring: |
这时用order再去请求就会报错,因为它们已经是两个世界的人了……
Nacos注册中心原理
Nacos配置管理
简单说就是方便管理配置,假如以后要修改 application的配置,就不要一个一个去修改了,直接统一修改而且还不需要重启,直接就是热更新。
在Nacos配置管理的配置列表里新建一个配置并发布:(ID命名也是有规矩的,看等下的代码就知道了)
对了上图的dateformat前面的空格打多了,只有两个,我找了一下午的bug。
配置获取步骤:
所以先在recoures创建bootstrap.yml,启动springboot时配置文件的优先级会高于application.yml(PS:在springcloud 的版本高于2020.x时会默认禁用bootstrap,需要先在pom里引入spring-cloud-alibaba-bootstrap 的依赖)。先在userservice 里引入maven坐标:
1 | <!-- nacos的配置依赖--> |
然后再在bootstrap.yml里配置:
1 | spring: |
然后在UserController里面编写一段时间显示的接口:
1 |
|
通过@Value 读取配置时实现热更新:如果是通过 @Value 来读取配置的,此时只需在使用 @Value 注入的变量所在类上添加注解 @RefreshScope 即可,此时你在 nacos 配置中心修改配置并发布后,可以发现服务能自动接收到一些更新信息,类似下图,此时也就实现了配置热更新,此时再访问微服务的接口,可以看到返回的信息已经发生了改变。或者使用 @ConfigurationProperties 来读取配置时,微服务读取配置中心的配置可以自动实现热更新,无需进行其他操作。
nacos 集群搭建
在测试环境下可以以单体模式启动 nacos ,但是 Nacos 在生产环境下都是部署为集群状态的。
搭建集群的基本步骤:
- 搭建数据库,初始化数据库表结构
- 下载nacos安装包,修改nacos配置,启动nacos集群
- 启动nginx作为反向代理
下面我们搭建一个以 Nginx 作为负载均衡,nacos 有三个节点的集群,三个nacos节点的 ip 都是 127.0.0.1,端口分别为8845、8846、8847。架构图如下:
Nacos 默认是将数据存储在内嵌数据库 Derby 中的,该数据库不属于生产可用的数据库,官方推荐的最佳实践是使用带有主从的高可用数据库集群。
下面我们只以单点的数据库为例来搭建。首先新建一个 mysql 数据库,命名为nacos,而后导入下面的SQL:
MySQL
1 | CREATE TABLE `config_info` ( |
配置 nacos
下载 nacos 安装包并解压后即安装完成,下面进行 nacos 集群的配置。
进入 nacos 安装目录的 conf 目录下,复制配置文件 cluster.conf.example 并重命名为 cluster.conf,给文件 cluster.conf 添加以下内容:
- 127.0.0.1:8845
- 127.0.0.1.8846
- 127.0.0.1.8847
类似如下:
然后继续修改 conf/application.properties 文件,在文件内添加以下内容,配置数据库连接信息,如下:
- spring.datasource.platform=mysql
- db.num=1
- db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
- db.user.0=root
- db.password.0=123456
以此一个 nacos 节点就已经配置完成,只需将 nacos 复制三份,然后分别修改三个文件夹中的application.properties,将 server.port 分别修改为 8845、8846、8847 即可。
分别启动这三个 nacos 节点即可,直接双击 bin/startup.cmd 文件即可启动,启动结果如下:
启动Nginx作为反向代理
上述步骤中启动 nacos 集群后,即可启动一个 Nginx 作为反向代理,nacos 客户端需要访问连接 nacos 服务端时,只需访问 Nginx 的服务即可。
Nginx 配置如下:
1 | upstream nacos-cluster { |
访问 http://localhost/nacos 即可访问到 nacos 集群,Nginx 会将接收到的请求负载均衡到三个 nacos 节点当中。
比如 nacos 节点需访问 nacos 集群时,项目配置文件如下:
1 | spring: |