在很多时候
kill -9 pid
并不是很友好的方法,那样会将我们正在执行请求给断掉,同时eureka
中服务依旧是处于在线状态,这个时候我们可以使用官方提供的actuator
来做优雅的关闭处理
- Actuator
spring-boot-actuator
模块提供了一个监控和管理生产环境的模块,可以使用http、jmx、ssh、telnet等拉管理和监控应用。审计(Auditing)、健康(health)、数据采集(metrics gathering)会自动加入到应用里面。
- 开始
如果对Eureka
不熟悉的可以参考:一起来学SpringCloud之-注册中心(Eureka/Consul)
- battcn-cloud-discovery
pom.xml导入
eureka-server
包
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
application.yml 配置内容
server:
port: 7001
spring:
application:
name: battcn-cloud-discovery
eureka:
instance:
hostname: localhost
prefer-ip-address: true
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
DiscoveryApplication 主函数启动类
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}
- battcn-cloud-hello
pom.xml导入
eureka
和actuator
,注意该处不能用tomcat
(原因还没找到,用tomcat报错,有兴趣的可以自己也试试)
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
application.yml 配置内容
server.port: 7002
spring.application.name: battcn-cloud-hello
endpoints.shutdown.enabled: true #开启优雅关闭方式
management.security.enabled: false #关闭安全认证
eureka:
instance:
hostname: localhost
prefer-ip-address: true
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:7001/eureka/
HelloApplication 主函数与测试方法
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class HelloApplication {
static Logger LOGGER = LoggerFactory.getLogger(HelloApplication.class);
@GetMapping("/h1")
public void home() {
for (int i = 1;i < 6;i++) {
try {
Thread.sleep(i * 500);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("[当前进度] - [{}]",i);
}
}
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
- 测试
1.分别启动battcn-cloud-discovery
和 battcn-cloud-hello
两个服务
2.GET请求访问 http://192.168.206.1:7002/h1
3.POST请求访问:http://192.168.206.1:7002/shutdown
- 日志分析
battcn-cloud-discovery
2017-08-20 11:50:38.257 INFO 6776 --- [nio-7001-exec-3] c.n.e.registry.AbstractInstanceRegistry : Registered instance BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 with status DOWN (replication=false)
2017-08-20 11:50:38.259 INFO 6776 --- [nio-7001-exec-8] c.n.e.registry.AbstractInstanceRegistry : Cancelled instance BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 (replication=false)
2017-08-20 11:50:38.765 INFO 6776 --- [nio-7001-exec-5] c.n.e.registry.AbstractInstanceRegistry : Registered instance BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 with status DOWN (replication=true)
2017-08-20 11:50:38.766 INFO 6776 --- [nio-7001-exec-5] c.n.e.registry.AbstractInstanceRegistry : Cancelled instance BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 (replication=true)
battcn-cloud-hello
2017-08-20 11:50:34.911 INFO 1304 --- [qtp161672347-19] com.battcn.HelloApplication : [当前进度] - [1]
2017-08-20 11:50:35.912 INFO 1304 --- [qtp161672347-19] com.battcn.HelloApplication : [当前进度] - [2]
2017-08-20 11:50:37.413 INFO 1304 --- [qtp161672347-19] com.battcn.HelloApplication : [当前进度] - [3]
2017-08-20 11:50:38.251 INFO 1304 --- [ Thread-28] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1c481ff2: startup date [Sun Aug 20 11:50:24 CST 2017]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@60dcc9fe
2017-08-20 11:50:38.252 INFO 1304 --- [ Thread-28] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application battcn-cloud-hello with eureka with status DOWN
2017-08-20 11:50:38.252 WARN 1304 --- [ Thread-28] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1503201038252, current=DOWN, previous=UP]
2017-08-20 11:50:38.252 INFO 1304 --- [ Thread-28] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
2017-08-20 11:50:38.252 INFO 1304 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002: registering service...
2017-08-20 11:50:38.253 INFO 1304 --- [ Thread-28] com.netflix.discovery.DiscoveryClient : Unregistering ...
2017-08-20 11:50:38.258 INFO 1304 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 - registration status: 204
2017-08-20 11:50:38.260 INFO 1304 --- [ Thread-28] com.netflix.discovery.DiscoveryClient : DiscoveryClient_BATTCN-CLOUD-HELLO/192.168.206.1:battcn-cloud-hello:7002 - deregister status: 200
2017-08-20 11:50:38.264 INFO 1304 --- [ Thread-28] com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
2017-08-20 11:50:38.265 INFO 1304 --- [ Thread-28] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2017-08-20 11:50:38.269 INFO 1304 --- [ Thread-28] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2017-08-20 11:50:38.270 INFO 1304 --- [ Thread-28] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans
2017-08-20 11:50:38.283 INFO 1304 --- [ Thread-28] o.e.jetty.server.AbstractConnector : Stopped ServerConnector@622fdb81{HTTP/1.1,[http/1.1]}{0.0.0.0:7002}
2017-08-20 11:50:38.283 INFO 1304 --- [ Thread-28] org.eclipse.jetty.server.session : Stopped scavenging
2017-08-20 11:50:38.290 INFO 1304 --- [ Thread-28] o.e.j.s.h.ContextHandler.application : Destroying Spring FrameworkServlet 'dispatcherServlet'
2017-08-20 11:50:38.291 INFO 1304 --- [ Thread-28] o.e.jetty.server.handler.ContextHandler : Stopped o.s.b.c.e.j.JettyEmbeddedWebAppContext@987455b{/,[file:///C:/Users/Levin/AppData/Local/Temp/jetty-docbase.3368921683179226836.7002/],UNAVAILABLE}
2017-08-20 11:50:39.414 INFO 1304 --- [qtp161672347-19] com.battcn.HelloApplication : [当前进度] - [4]
2017-08-20 11:50:41.915 INFO 1304 --- [qtp161672347-19] com.battcn.HelloApplication : [当前进度] - [5]
从上述两端日志中可以看出,当我们发送shutdown
命令的时候,会先通知eureka
做服务下线处理,防止后续请求继续获取服务列表,然后当前服务的请求会继续执行,直到处理完毕后关闭进程,有兴趣的可以自己看看org.springframework.boot.actuate.endpoint.ShutdownEndpoint
- 说点什么
本章代码(battcn-cloud-discovery/battcn-cloud-hello):https://git.oschina.net/battcn/battcn-cloud/tree/master/battcn-cloud-shutdown
如有问题请及时与我联系
- 个人QQ:1837307557
- battcn开源群(适合新手):391619659
- Spring Cloud中国社区①:415028731
- Spring For All 社区⑤:157525002