《红色高跟鞋》--- 单曲循环中。。。
项目环境:
spring boot :2.2.1
spring cloud:Hoxton
jdk:1.8
各模块依赖包:
注册中心:spring-cloud-starter-netflix-eureka-serve
服务提供:spring-cloud-starter-netflix-eureka-client
服务调用:spring-cloud-starter-openfeign
网关:spring-cloud-starter-gateway
配置中心:spring-cloud-config
注:下一篇学习使用 apollo 配置中心
项目源码:https://github.com/XGLLHZ/springcloud-frame.git
项目父包:
新建 spring boot 项目,删除 src 等文件(具体可在源码中见),父包负责项目的架构,为子模块提供依赖管理、版本管理等。一下 pom 文件为最终结果。
<!-- 继承 spring boot 父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version> <!-- spring boot 版本 -->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.huangzi</groupId>
<artifactId>frame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>frame</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <!-- jdk 版本 -->
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version> <!-- spring cloud 版本 -->
</properties>
<!-- 引入子模块 -->
<modules>
<module>frame-eureka</module> <!-- 注册中心 -->
<module>frame-config</module> <!-- 配置中心 -->
<module>frame-common</module> <!-- 公共模块 -->
<module>frame-gateway</module> <!-- 网关 -->
<module>frame-provider</module> <!-- 服务提供者 一号 -->
<module>frame-providers</module> <!-- 二号 -->
<module>frame-consumer</module> <!-- 服务消费者 一号 -->
<module>frame-consumers</module> <!-- 二号 -->
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- eureka test 服务提供 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 声明式 http请求 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- 熔断器监控相关 -->
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
注:在分布式开发中,需要同时启动多个 spring boot 项目,所以要让 idea 支持同时运行多个项目,则点击 Edit Configrations ,把下图中的勾去掉就行。
注册中心:
服务提供者、消费者、配置中心、网关等服务豆=都将被注册到注册中心,主要用来监控这些服务是否挂掉(上线后)。
在项目上新建 module (frame-eureka),修改 pom 文件,使其继承父工程,并引入相关依赖,在启动类上加上 @EnableEurekaServer 注解,开启注册功能。然后配置配置中心。
<!-- 继承父工程 -->
<parent>
<groupId>org.huangzi</groupId>
<artifactId>frame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.huangzi.frame</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka server 注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
注:各位客官会发现每个模块都有 web 依赖(除了 frame-gateway),不放在父 pom 中统一管理的原因是 spring-cloud-starter-gateway 与 web 依赖互相看不惯,如果 web 依赖放在 父 pom 中那就等于 frame-gateway 模块一出生就拥有了 web 包,那必然会与 gateway 依赖厮杀,所以不得不将 web 依赖放在其余每个子模块中,这样就避免了冲突。同样,eureka-server 这个依赖中也包含 web 包,所以将其放在子模块中。
# eureka 配置
spring:
application:
name: frame-eureka
profiles:
active: dev
http:
encoding:
enabled: true
charset: utf-8
force: true
server:
port: 8081
eureka:
instance:
hostname: frame-eureka # 服务名
client:
register-with-eureka: false # 是否将自身注册到 eureka 注册中心
fetch-registry: false # 是否要从 eureka 注册中心获取注册信息
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # eureka 注册中心注册地址
打开浏览器访问 http://localhost:8081/eureka/,若无误,则会看到 注册中心页面。
服务提供:
这里的服务提供者是指项目中的公告模块,比如电商网站中的订单、支付、用户等模块,这样就减少了相关开发。
同样新建 moudle(frame-provider),修改 pom 文件使其继承父工程,引入相关依赖,在启动类上添加 @EnableEurekaClient,这样该服务就会被注册在注册中心。然后修改配置中心。
<!-- 继承父工程 -->
<parent>
<groupId>org.huangzi</groupId>
<artifactId>frame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.huangzi.frame</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
# frame-provider 配置
spring:
application:
name: frame-provider
profiles:
active: dev
http:
encoding:
enabled: true
charset: utf-8
force: true
server:
port: 10031
servlet:
context-path: /api31
tomcat:
connection-timeout: 5000
eureka:
instance:
hostname: localhost #因为是本地,所以 hostname 必须为 localhsot
server:
enable-self-preservation: true #开启自我保护
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/ #注册中心地址
注:1、在每个需要被注册到注册中心的服务的 yml 文件配置需要注意:lease-renewal-interval-in-seconds 和 lease-expiration- duration-in-seconds 。ease-renewal-interval-in-seconds:服务每隔多少秒给注册中心发一次心跳,lease-expiration-duration-in-seconds :若注册中心在多少秒之内没有接收到某个服务的心跳则会将其从注册中心剔除。官方给出的参考时间为 30s 和 90s ,这个需要谨慎配置,如果需要的话(完全可以不配置,若不配置则在注册中心会出现一串字符串的红色标志,但不影响)。
2、对于上面的问题,可以开启 enable-self-preservation 这个配置来解决,意为自我保护。默认情况下,如果注册中心在一段时间呢你没有接收到某个服务的心跳则会将其剔除,但是如发生了网络问题,就会出现注册中心疯狂剔除服务的问题,这时,如果开启自我保护模式,若是注册中心在一段时间剔除太多服务的话,注册中心的服务就会进入自我保护模式,这样注册中心就会保留注册中心的数据,直到网络问题恢复,服务的自我保护模式就会解除。
然后在 frame-provider 模块中写一个 /provide/test/hello 接口,返回 I am from provide server!
在注册中心已经启动的情况下,启动服务提供者 frame-provider,若无误,则会在注册中心看到服务提供者。(请忽略 frame-config 服务)。
服务消费:
服务消费就是服务调用者,也就是 frame-consumer 服务调用 frame-provider 服务,官方采用 feign 来调用,声明式的 http ,好用的一批。首先新建 module(frame-consumer),修改 pom 文件,引入相关依赖,使其继承父工程,然后配置配置文件。在启动类上添加 @EnableEurekaServer、@EnableEurekaClients 注解,第一个注解是使其注册在注册中心,第二个注解是开启 feign。
<!-- 继承父工程 -->
<parent>
<groupId>org.huangzi</groupId>
<artifactId>frame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.huangzi.frame</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
# frame-consumer 配置
spring:
application:
name: frame-consumer
profiles:
active: dev
http:
encoding:
enabled: true
charset: utf-8
force: true
server:
port: 10041
servlet:
context-path: /api41
tomcat:
connection-timeout: 5000
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: true #打开自我保护
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/ #注册中心地址
然后在模块内 新建 TestService 接口,然后新建 Testcontroller,调用接口,然后测试。
/**
* @author: XGLLHZ
* @date: 2019/12/12 下午3:19
* @description: 测试服务消费者事务层接口
*/
@FeignClient(value = "frame-provider") #这个注解指向了 frame-provider 服务
public interface TestService {
#也就是实际上在这个接口里调用了 frame-provider 服务内的 /api31/provide/test/hello 接口
@RequestMapping("/api31/provide/test/hello")
String test();
}
@RestController
@RequestMapping("/consume/test")
public class TestController {
@Autowired
TestService testService;
@RequestMapping("/hello")
public String test() {
return testService.test();
}
}
然后打开然后依次启动 注册中心,服务提供者,消费者,访问 http://localhost:10041/api41/consume/test/hello,若无误,则会返回 I am from provide server!。
网关:
网关是用来的统一处理请求的,具体作用大家度娘哈。这里没有采用 zuul,而是采用 spring-cloud-gateway。首先新建 module(frame-gateway),修改 pom 文件,使其继承父工程,然后添加 spring-cloud-starter-gateway,注意这里没有 web 包,然后在启动了添加 @EnableEurekaClient,网关中最重要的就是配置中心。
# gateway 配置
spring:
application:
name: frame-gateway
profiles:
active: dev
http:
encoding:
enabled: true
charset: utf-8
force: true
cloud:
gateway:
routes:
- id: api41
uri: http://localhost:10041
predicates:
- Path=/api41/consume/test/hello
#意为:当你访问 http://localhost:8082/api41/consume/test/hello时,网关会自动转发到 http://localhost:10041/api41/consume/test/hello
#- id: api42
# uri: http://localhost:10042
# predicates:
# - Path=/api42/consumes/test/hello
server:
port: 8082
tomcat:
connection-timeout: 5000
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: true #开启自我保护
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/ #注册中心地址
依次启动 frame-eureka、frame-provider、frame-consumer、frame-gateway服务,访问 http://localhost:8082/api41/consume/test/hello,若无误,则会返回 I am from provide server!。
配置中心:
目前我们已经有四个服务了,正常开发中会有好多个服务提供者、消费者等服务,那也就是说我们要去配置好多个服务的配置,配一遍,起一遍,就很累,所以就有了配置中心,统一管理配置。这里采用 spring-cloud-config,一般都是将配置文件放在 git,git 上有一个回调地址,会每当有新的 push 时,就会自动刷新配置。首先新建 module(frame-config),修改 pom 文件,使其继承父工程,引入相关依赖,在启动类上添加 @EnableConfigServer 使其成为配置中心,然后修改配置文件。
<!-- 继承父模块 -->
<parent>
<groupId>org.huangzi</groupId>
<artifactId>frame</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.huangzi.frame</groupId>
<artifactId>config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>config</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
在 git 上创建配置文件,本项目 git 上的配置文件放在 frame-config/ config 下,比如说 frame-provider 的配置文件是 frame-provider-config.yml。
# config 配置
spring:
application:
name: frame-config
http:
encoding:
enabled: true
charset: utf-8
force: true
cloud:
config:
server:
git:
uri: https://github.com/XGLLHZ/springcloud-frame.git #git 仓库地址
search-paths: frame-config/config #配置文件目录
username: XGLLHZ #git 用户名
password: ****** #git 密码
default-label: master #分支
server:
port: 8083
servlet:
context-path: /api
tomcat:
connection-timeout: 5000
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: true 开启自我保护
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/ #注册中心地址
然后将 frame-provider 模块中的 application.yml 文件删除,新建 bootstrap.yml 文件(spring boot 项目启动时优先加载 bootstrap.yml 文件),在里面添加如下内容:
# frame-provider 配置 git 配置
spring:
cloud:
config:
uri: http://localhost:8083/api #配置中心地址
name: frame-provider-config #git 上的配置文件名
label: master #分支
discovery:
enabled: true
然后启动配置中心,启动 frame-provider,这时候 frame-provider 的端口号是 10031,然后修改 frame-config/config/frame-provider-config.yml 文件,将 port 改为 10033,然后 push 到 git ,这时候重新启动 frame-provider,若无误,则 端口号已经变味10033。
最后再放一张图,别问我为什么,我就是想放!
《杨千嬅-2019世界巡回演唱会-天津站》!!!