特别注意,SpringBoot、SpringCloud、Openfeign等依赖的版本必须相匹配,不然会报各种错。具体版本对应关系看官网。或者看:https://start.spring.io/actuator/info
父pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <modules> <module>cloud-order-service1</module> <module>cloud-order-service2</module> <module>cloud-order-consumer</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xcg</groupId> <artifactId>cloudapp</artifactId> <version>1.0.0</version> <name>cloudapp</name> <description>Demo project for Spring Boot</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> </properties> <!--父pom管理的依赖--> <dependencyManagement> <dependencies> <!--启动数据库连接--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--数据库连接池--> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.23</version> </dependency> <!--MySQL数据库连接驱动--> <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.4.0</version> </dependency> <!--mybatis-spring-boot-starter是一个Maven项目,用于自动装配MyBatis框架到Spring Boot项目中。--> <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> <!--用户鉴权--> <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>4.4.0</version> </dependency> <!--SqlServer数据库连接驱动--> <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>12.6.2.jre8</version> </dependency> <!--Oracle数据库连接驱动--> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>19.3.0.0</version> </dependency> <!--用于发送http请求--> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.1.3</version> </dependency> <!--客户端/服务消费者 负载均衡--> <!--LoadBalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> <version>4.0.4</version> </dependency> <!--声明式的Http客户端,服务的消费端替代RestTemplate发送请求,更加简洁。--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>4.1.2</version> </dependency> <!--Sentinel是Spring Cloud Alibaba提供的一个专门用于服务容错、服务熔断、服务限流的微服务组件--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2023.0.1.2</version> </dependency> <!--sentinel持久化依赖,采用Nacos作为规则配置数据源。--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.8.8</version> </dependency> </dependencies> </dependencyManagement> <!--每个子Module都自动继承的依赖--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.3.1</version> </dependency> <!-- 使用SpringBoot自带的log组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> <!--Aop切面--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.51</version> </dependency> <!--缩减java类的代码编写--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.34</version> <scope>provided</scope> </dependency> <!--辅助类 StringUtils--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.14.0</version> </dependency> <!--SpringCloud依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2023.0.2</version> <type>pom</type> <scope>import</scope> </dependency> <!--导入SpringCloudAlibaba--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2023.0.1.2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-commons</artifactId> <version>4.1.4</version> </dependency> <!--导入nacos服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2023.0.1.2</version> </dependency> <!--导入nacos服务配置中心--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2023.0.1.2</version> </dependency> <!--在SpringCloud应用中配置和初始化一些必要的设置 bootstrap.yaml--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <version>4.1.3</version> </dependency> </dependencies> <!--编译插件,使用maven插件编译项目。--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
@SpringBootApplication @EnableDiscoveryClient public class OrderMain1 { public static void main(String[] args) { SpringApplication.run(OrderMain1.class, args); } }
子服务Module配置bootstrap.yaml 在同一台机器上部署运行的话,还是得加上server 》 port端口配置的,不然多个服务的话端口冲突。
服务注册nacos总是在public命名空间下的问题:配置中的discovery下和config下都要配置namespace,值要一样,不然服务就会默认注册到public命名空间下。其他版本的暂时不清楚。
spring: application: # Nacos添加配置,格式:${prefix}-${spring.profiles.active}.${file-extension} # 示例:cloud-order-service-dev.yaml name: cloud-order-service profiles: active: dev # 配置环境变量,Nacos配置DataId的一部分。自定义例如:dev test pro cloud: nacos: discovery: server-addr: localhost:8848 # Nacos作为服务中心地址 namespace: 8e23ce60-9f28-4fa7-875a-5e0d61b533d5 # Nacos配置命名空间的id,默认public config: server-addr: localhost:8848 # Nacos作为配置中心地址 file-extension: yaml # Nacos配置后缀 group: DEFAULT_GROUP # Nacos配置分组 namespace: 8e23ce60-9f28-4fa7-875a-5e0d61b533d5 # Nacos配置命名空间的id,默认public username: nacos # Nacos登录账户 password: 123456 # Nacos登录密码 sentinel: transport: web-context-unify: false # 默认true 将调用链路收敛, 导致链路流控效果无效 dashboard: localhost:8080 # 配置sentinel dashboard地址。 port: 8719 # 默认8719端口,如果被占用,则从8719递增检查未被占用的端口 # sentienl 数据源配置 参考:https://blog.csdn.net/qq_42402854/article/details/127379403 datasource: nacos-flow-rule1: # 自定义数据源名称,可以随便定义,目的是为了区分出每条规则,无实际应用。 nacos: server-addr: localhost:8848 # Nacos地址 username: nacos # Nacos账户 password: 123456 # Nacos密码 namespace: 8e23ce60-9f28-4fa7-875a-5e0d61b533d5 # Nacos命名空间必须使用id dataId: cloud-order-service-flow # Sentinel需要同步Nacos创建的流控配置DataId rule-type: flow # 规则类型 flow:流控规则; data‐type: json # 默认值json,可以不填。 # feign开启Sentinel支持 feign: sentinel: enabled: true # Nacos配置DataId命名说明 # ${prefix}-${spring.profiles.active}.${file-extension} # prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。 # spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension} # file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
Nacos创建配置,子服务Module不需要再配置application.yaml,使用Nacos配置中心后,把application.yaml的配置放到Nacos中,然后就可以把application.yaml删除了。
本地application.yaml也可以不删除,但如果Nacos的配置和本地application.yaml中的配置的key相同,那会采用本地的配置,Nacos配置不会覆盖本地。
如果修改了Nacos的系统配置,需要重启服务实例。
命名空间:8e23ce60-9f28-4fa7-875a-5e0d61b533d5
Data ID:cloud-order-service-dev.yaml
Group:DEFAULT_GROUP
配置格式:YAML
配置内容:如下,如果在本机复制多个子服务项目,把端口的配置去掉,使用各个子服务项目自定的端口,避免端口冲突。
server: port: 8001 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # MySQL驱动包 url: jdbc:mysql://localhost:3306/springcloudtest?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&failOverReadOnly=false username: root password: root mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.xcg.dto # 自定义配置 config: info: this is development environment!!!
子服务测试Controller
@RestController @RefreshScope //支持Nacos配置中心动态刷新功能 @RequestMapping("/test") public class TestController { @GetMapping("/getName") public String getName() { return "jay111"; } @GetMapping("/getStu") public StuDto getStu() { return new StuDto() {{ setAge(23); setName("jay111"); setSn("111111"); }}; } @PostMapping("/queryStu") public StuDto queryStu(@RequestBody StuDto dto) { return new StuDto() {{ setAge(dto.getAge()); setName("George111"); setSn("111111"); }}; } }
可以复制多个子Module,端口改一下,然后把Controller返回值改一下,能区分出客户/消费端调用了不同端口的服务就行。
子服务nacos配置类,在nacos上 配置管理》配置列表》创建配置,然后可以对应java类
@Data @Component @RefreshScope //支持Nacos配置中心动态刷新功能 public class NacosConfig { //绑定的是nacos配置中心发布的配置 @Value("${config.info}") private String configInfo; }
客户端Module需要使用负载均衡、使用openfeign替代RestTemplate简化请求的发送。
客户端pom,继承了父pom,不需要写版本号。
<dependencies> <!--客户端/服务消费者 负载均衡--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <!--声明式的Http客户端,替代RestTemplate发送请求,更加简洁。--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
客户端启动方法,标记@EnableDiscoveryClient,注册进nacos。标记@EnableFeignClients,启用feign。
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class OrderConsumerMain { public static void main(String[] args) { SpringApplication.run(OrderConsumerMain.class, args); } }
使用feign,创建客户端映射服务接口,标记服务名称,方法签名。使用feign替换RestTemplate,这里就不贴RestTemplate的代码了。
/** * 启用OpenFeign,替代RestTemplate发送Http请求。 * 指定服务名:cloud-order-service * 此处需要是注册进nacos的服务名称(ServiceId),如果不一致会报错。 * */ @FeignClient(value = "cloud-order-service") public interface CloudOrderFeignService { /** * 方法签名要和注册服务中的一致 * */ @GetMapping("/test/getName") public abstract String getName(); @GetMapping("/test/getStu") public abstract StuDto getStu(); @PostMapping("/test/queryStu") public abstract StuDto queryStu(StuDto dto); }
调用远端服务:
@Autowired private CloudOrderFeignService cloudOrderFeignService; @GetMapping("/getStu") public Object getStu() { StuDto res = cloudOrderFeignService.getStu(); return res; } @PostMapping("/queryStu") public Object queryStu(@RequestBody StuDto dto) { StuDto res = cloudOrderFeignService.queryStu(dto); return res; }
参考文章:
https://spring.io/projects/spring-cloud-alibaba
https://nacos.io/zh-cn/docs/ecology/use-nacos-with-spring-cloud/
https://blog.csdn.net/m0_65152767/article/details/136469434
https://blog.csdn.net/mqiqe/article/details/139507509
https://zhuanlan.zhihu.com/p/691870005