Tips:
springcloud版本:Finchley.RELEASE
springboot版本:2.0.8.RELEASE
jdk:1.8
rabbitmq : 用默认用户guest
当你看到这篇时,你可能看了好多篇关于配置刷新的文章,但是都不能解决你的问题,要么版本不一致,配置出问题,mq有问题等等,放轻松,慢慢往下看,然后就很舒服。折腾了一天的坑,踩过了大大小小的坑,终于把config利用bus-amqp基于webhook的自动刷新给解决了。
首先,快速搭建一套eureka server、eureka client 、config-server ,@EnableDiscoveryClient在F版本可以省略了,三步走依赖、注解、配置。
一、 搭建项目
- 我最简化了配置文件,能不写的就不写,以防我们在刚学的时候担心这个配置一定要写吗?不写有什么影响呢?各种疑虑影响游戏体验。有兴趣的可以自己研究cloud里面的配置。在父工程里添加版本号,公共模块
spring-boot-starter-web
,spring-boot-starter-actuator
,依赖太长就不贴了。代码链接在下面,就为了让你先看一眼配置。 - eureka server
依赖:
- eureka server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
注解:@SpringBootApplication @EnableEurekaServer
配置:
### 注意 文件名为application.yml
spring:
application:
name: eureka-server
server:
port: 8761
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: false
register-with-eureka: false
- eureka client
依赖:
- eureka client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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-bus-amqp</artifactId>
</dependency>
注解:@SpringBootApplication
配置:
### 注意 文件名为 bootstrap.yml
server:
port: 8082
spring:
application:
name: comsumer
cloud:
config:
profile: dev # profile对应config server所获取的配置文件中的{profile}
label: master # 指定Git仓库的分支,对应config server所获取的配置文件的{label}
discovery:
enabled: true
service-id: config-server ##配置中心服务名
name: eureka-client ##仓库中对应配置的名子
rabbitmq:
host: 192.168.246.134 ##我虚拟机地址
- config server
依赖:
- config server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
注解:@SpringBootApplication
,@EnableConfigServer
配置:
### 注意 文件名为application.yml
spring:
application:
name: config-server
cloud:
config:
server:
git:
# Git仓库地址 请写自己的
uri: https://github.com/Guiee/spring-cloud-config-repo.git
rabbitmq:
host: 192.168.246.134
eureka:
instance:
prefer-ip-address: true
management:
endpoints:
web:
exposure:
include: "*"
不想自己写可以直接clone下来,看看结果,项目代码:https://github.com/Guiee/springcloud-config
二、 安装rabbitmq
这个网上搜一搜就ok了,注意的是如果mq安装在虚拟机里,本地主机是无法用guest用户登录的。
- 到这 ,git仓库你总得有吧,不想建就fork一下我的,省事儿懒人链接
三、依次启动 eureka server(8761)、config server(8080)、eureka client(8082)
- 然后启动项目看一看有没有啥问题
- 访问http://localhost:8082/env
- 修改github中的env的值,发送 post 请求
http://localhost:8080/actuator/bus-refresh
,可以使用psotman 或者在终端curl -X POST http://localhost:8080/actuator/bus-refresh
postman - 在访问http://localhost:8082/env 看下值是否刷新了
-
这时候可以看下idea里控制台的输出,也可以看下rabbit的消息是否被消费了,如下折线。
rabbitmq页面截图.jpg
四、 webhook自动刷新
在config-server中把bus-refresh端点暴露出来,默认actuator只暴露 info
health
我就全暴了。这里省略建仓库那些的。
management:
endpoints:
web:
exposure:
include: "*"
可能很多人用 Finchley.RELEASE
这个版本向config server 发送 post http://localhost:8080/actuator/bus-refresh
都能成功,但是一用webhook就不能成功,要么404,405要么就报乱七八槽的错,还有config-server刷新了,客户端没有刷新。坑只有自己踩过,才知道是真的坑,哈哈。
- 利用natapp小工具,实现内网穿透,把下面这个网址拷到webhook的Payload URL里,例 如
http://werv67.natappfree.cc/refresh
,划重点 至于这里为什么写的是/refresh
,而不是/actuator/bus-refresh
或者/monitor
,因为这里就是坑,具体往下看。
natapp运行.png
这里先把项目启动起来,然后再添加webhook,如果你能看到下面那个绿色小箭头就基本成功了。
image.png
把env的值修改一下,然后去eureka client中访问一下,我的地址是http://localhost:8082/env
,如果值刷新了,就ok了。
image.png
四、 坑点
上面说的那个url的事情, 主要是github那个Payload URL回调需要返回值,用 http://xxx/monitor , 还是 http://xxx/bus/refresh都不管用。所以我在config-server里加了一个controller,用来转发,只用把yml里config-server服务名设置一下spring.application.name=xxx
,其他的都不用修改,或者你想换个url来转发都可以,看你心情。
@RestController
public class ConfigController {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String serviceId;
@PostMapping("/refresh")
public Object sync() {
Map<String, Integer> map = new HashMap<String, Integer>();
ServiceInstance serviceInstance = loadBalancerClient.choose(serviceId);
System.out.println(serviceId);
String url = String.format("http://%s:%s/actuator/bus-refresh", serviceInstance.getHost(), serviceInstance.getPort());
System.out.println(url);
restTemplate.postForObject(url, map, Object.class);
map.put("code", 0);
return map;
}
}
写的可能很粗糙,很多地方没写清楚,但这是真真实实动态刷新了,没明白的可以简信我。
网友评论