随着项目开发的推荐,原来由多个单服务组成的系统之间,相互关联,互相调用的需求越来越多,由来通过API接口进行调用,但是随着系统复杂度的提升,由原来通过API进行调用的方式,越来越无法满足需求,而且多个服务之间的治理也存在问题,因此,计划将服务升级,通过微服务的方式解决服务发现,服务治理。
通过比较,选择了,目前使用比较多的Nacos做为注册中心
1.注册中心Nacos的安装与启动
Nacos的安装相对简单,在具体使用过程中,Nacos的文档说明中有完成的安装介绍,包括不同操作系统,不同安装方式的介绍,在此系统中,所有的安装均采用Docker的形式进行
具体Docker-compose文件的配置代码如下:
version: "3"
services:
nacos1:
container_name: nacos-server01
hostname: nacos-server01
image: nacos/nacos-server
privileged: true
environment:
- MODE=standalone # 独立方式配置
- PREFER_HOST_MODE=hostname
- NACOS_SERVERS=nacos-server01:8848 # nacos-server02:8848 nacos-server03:8848
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=XXX
- MYSQL_SERVICE_PORT=XXX
- MYSQL_SERVICE_USER=XXX
- MYSQL_SERVICE_PASSWORD=XXX
- MYSQL_SERVICE_DB_NAME=XXX
- MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=10000&socketTimeout=3000&autoReconnect=true&useSSL=false&serverTimezone=UTC
- JVM_XMS=1024m
- JVM_XMX=1024m
- JVM_XMN=1024m
volumes:
- $PWD/nacos/cluster-logs/nacos1:/home/nacos/logs
- $PWD/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties
ports:
- 8845:8848
- 9848:9848
- 9555:9555
restart: on-failure
通过以上配置,可以很方便的启动Nacos服务,特别注意端口的映射,在服务器上要放行所需要的端口,否则无法被服务注册。
2. 微服务的注册配置
由于SpringBoot,SpringCloud以及Nacos包,有比较严格的配对要求,刚开始,由于所使用的Springboot的版本,并没有对应的Nacos的包,因此,对SpringBoot的核心版本进行了升级,考虑到除了Nacos包以外的包,也有兼容性要求,经过测试,在项目中使用了SpringBoot2.6.12这个版本,并且配合以下SpringCloud以及Nacos的包进行使用:
<!-- Nacos服务包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.0</version> <!--$NO-MVN-MAN-VER$-->
</dependency>
以上包可以配合使用,并使项目顺利进行了运行,主要的配置文件
bootstrap.yml文件的配置如下:
# nacos 配置中心
spring:
cloud:
nacos:
server-addr: '@nacos.config.host@'
discovery:
username: '@nacos.config.username@'
password: '@nacos.config.password@'
namespace: '@nacos.config.namespace@'
#config:
# server-addr: ${dreamteam.nacos.config.ip}:${dreamteam.nacos.config.port}
spring.cloud.nacos.discovery.ip: ${dreamteam.nacos.config.discovery.ip}
spring.cloud.nacos.discovery.port: ${dreamteam.nacos.config.discovery.port}
所使用变量,主要是因为,直接放到application.yml中每次启动,找不到配置,使用默认的本地进行启动,因此才通过传参数的形式进行,里面所涉及到
1.1 @@之间的变量
@XXX@
之间的参数是通过POM文件进行配置的
示例如下:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profileActive>dev</profileActive>
<nacos.config.host>192.168.xxx.xxx:xxx</nacos.config.host>
<nacos.config.username>userName</nacos.config.username>
<nacos.config.password>password</nacos.config.password>
<nacos.config.namespace>namespace</nacos.config.namespace>
</properties>
</profile>
</profiles>
1.2 ${}中的变量
${}
中的变量来自于appliation-prod.yml配置
nacos:
config:
discovery.ip: ${SERVER_HOST_IP}
discovery.port: ${SERVER_HOST_PORT}
application-prod.yml中的配置,由于不同的服务器可能会有不同的配置,此项目项目,接收的参数,来自docker-compose中的环境参数配置
environment:
TZ: "Asia/Shanghai"
SERVER_HOST_IP:XXX.XXX.XXX.XXX
SERVER_HOST_PORT: XXX
然后在Application.java中注解上即可启动和注册
@EnableDiscoveryClient
增加此注解后,即可在注册中心注册
1.3 OpenFeign调用
@EnableFeignClients(basePackages = { "包1", "包名2 }) // 增加注解
因为使用了多个包,所以这里注册指定了包名,否则可能无法扫描到
需要使用到的包为:
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.0</version> <!--$NO-MVN-MAN-VER$-->
</dependency>
上面已经提到,如果不用,可以不增加此包,若其它包有冲突或兼容性,记得需要排除一下,比如这个项目中就做了排除
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${feign.version}</version>
<exclusions>
<exclusion>
<artifactId>feign-core</artifactId>
<groupId>io.github.openfeign</groupId>
</exclusion>
</exclusions>
</dependency>
<!--增加了-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>${feign-okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
此项目中使用了okhttp的包,因此需要增加相关的配置以及引入包,在application.yml中的配置如下:
feign:
okhttp:
enabled: true
至此,项目配置完成,注册服务也配置完成
3.网关的使用
由于网关是新增加项目,因此使用了,2.3.X的SpringBoot包,同时对使用的包也进行了升级
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
其它配置类似
同时增加了sentinel的流量监控系统,具体搭建,sentinel-dashboard也是通过docker来完成的,代码如下:
version: '3'
services:
sentinel-dashboard:
image: bladex/sentinel-dashboard
container_name: sentinel-dashboard
restart: always
environment:
JAVA_OPTS: "-Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard"
ports: #避免出现端口映射错误,建议采用字符串格式 8080端口为Dockerfile中EXPOSE端口
- "8849:8858"
volumes:
- $PWD/logs:/root/logs
在application中增加sentinel的配置即可
spring:
cloud:
sentinel:
eagrt: true #提前触发初始化
transport:
eager: true
#当前服务的ip
clientIp: 192.168.20.158
port: ${server.port}
dashboard: 192.168.20.207:8849
即可完成配置,若不需要sentinel-dashboard则不需要添加相当配置与搭建服务
4.结束
至此所有配置全部完成,以上仅为部分关键代码,并且在测试和开发环境中使用,具体应用到生产环境中,需要增加安全相关的配置等