eureka监听各服务状态,下线、重连等,并做相应的处理
来源:互联网 发布:快手直播人气软件 编辑:程序博客网 时间:2024/05/19 17:02
在一些场景下,我们需要监听eureka服务中心的一些状态,譬如某个微服务挂掉了,我们希望能监听到,并给管理员发送邮件通知。
Eureka的server端会发出5个事件通知,分别是:
EurekaInstanceCanceledEvent 服务下线事件
EurekaInstanceRegisteredEvent 服务注册事件
EurekaInstanceRenewedEvent 服务续约事件
EurekaRegistryAvailableEvent Eureka注册中心启动事件
EurekaServerStartedEvent Eureka Server启动事件
我们可以从源码中很方便地看到
eureka的server端源码一共也没几个类,Controller是给界面用的,还有一些配置类,我们简单来看几个。
@Configuration@CommonsLogpublic class EurekaServerInitializerConfiguration implements ServletContextAware, SmartLifecycle, Ordered { ... @Override public void start() { new Thread(new Runnable() { @Override public void run() { try { //TODO: is this class even needed now? // 初始化eureka server eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); log.info("Started Eureka Server"); // 传递eureka注册事件,找来找去没看到有listen去处理这件事件 // spring包中没有去处理,如果我们有需要可以自己处理 // https://github.com/spring-cloud/spring-cloud-netflix/issues/1726 publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig())); // 设置在spring容器关闭的时候执行stop方法 EurekaServerInitializerConfiguration.this.running = true; publish(new EurekaServerStartedEvent(getEurekaServerConfig())); } catch (Exception ex) { // Help! log.error("Could not initialize Eureka servlet context", ex); } } }).start(); } @Bean public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry, EurekaServerContext serverContext) { return new EurekaServerBootstrap(this.applicationInfoManager, this.eurekaClientConfig, this.eurekaServerConfig, registry, serverContext); } ...}
@CommonsLogpublic class EurekaServerBootstrap { .... public void contextInitialized(ServletContext context) { try { //初始化eureka环境 initEurekaEnvironment(); //初始化eureka上下文 initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); } catch (Throwable e) { log.error("Cannot bootstrap eureka server :", e); throw new RuntimeException("Cannot bootstrap eureka server :", e); } } protected void initEurekaEnvironment() throws Exception { log.info("Setting the eureka configuration.."); //如果在云环境中运行,需要传递java命令行属性-Deureka.datacenter = cloud,以便Eureka客户端/服务器知道初始化AWS云特定的信息 String dataCenter = ConfigurationManager.getConfigInstance() .getString(EUREKA_DATACENTER); if (dataCenter == null) { log.info( "Eureka data center value eureka.datacenter is not set, defaulting to default"); ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT); } else { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter); } //eureka 运行环境,java命令行属性-Deureka.environment=eureka-client-{test,prod} String environment = ConfigurationManager.getConfigInstance() .getString(EUREKA_ENVIRONMENT); if (environment == null) { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); log.info( "Eureka environment value eureka.environment is not set, defaulting to test"); } else { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment); } } // eureka使用XStream来对json、xml格式的转换 protected void initEurekaServerContext() throws Exception { // 向后兼容 //注册状态转换器 JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH); XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH); //判断是否亚马逊的数据中心 if (isAws(this.applicationInfoManager.getInfo())) { this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager); // this.awsBinder.start(); } //初始化eureka server上下文 EurekaServerContextHolder.initialize(this.serverContext); log.info("Initialized server context"); // 从相邻的eureka节点复制注册表 int registryCount = this.registry.syncUp(); // 默认每30秒发送心跳,1分钟就是2次 // 修改eureka状态为up this.registry.openForTraffic(this.applicationInfoManager, registryCount); // 注册所有监控 EurekaMonitors.registerAllStats(); } ...}
public class InstanceRegistry extends PeerAwareInstanceRegistryImpl implements ApplicationContextAware { private static final Log log = LogFactory.getLog(InstanceRegistry.class); private ApplicationContext ctxt; private int defaultOpenForTrafficCount; public InstanceRegistry(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, ServerCodecs serverCodecs, EurekaClient eurekaClient, int expectedNumberOfRenewsPerMin, int defaultOpenForTrafficCount) { super(serverConfig, clientConfig, serverCodecs, eurekaClient); this.expectedNumberOfRenewsPerMin = expectedNumberOfRenewsPerMin; this.defaultOpenForTrafficCount = defaultOpenForTrafficCount; } public void setApplicationContext(ApplicationContext context) throws BeansException { this.ctxt = context; } public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) { super.openForTraffic(applicationInfoManager, count == 0 ? this.defaultOpenForTrafficCount : count); } public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { this.handleRegistration(info, leaseDuration, isReplication); super.register(info, leaseDuration, isReplication); } public void register(InstanceInfo info, boolean isReplication) { this.handleRegistration(info, this.resolveInstanceLeaseDuration(info), isReplication); super.register(info, isReplication); } public boolean cancel(String appName, String serverId, boolean isReplication) { this.handleCancelation(appName, serverId, isReplication); return super.cancel(appName, serverId, isReplication); } public boolean renew(String appName, String serverId, boolean isReplication) { this.log("renew " + appName + " serverId " + serverId + ", isReplication {}" + isReplication); List<Application> applications = this.getSortedApplications(); Iterator var5 = applications.iterator(); while(var5.hasNext()) { Application input = (Application)var5.next(); if (input.getName().equals(appName)) { InstanceInfo instance = null; Iterator var8 = input.getInstances().iterator(); while(var8.hasNext()) { InstanceInfo info = (InstanceInfo)var8.next(); if (info.getId().equals(serverId)) { instance = info; break; } }//这里发布重连事件 this.publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId, instance, isReplication)); break; } } return super.renew(appName, serverId, isReplication); } protected boolean internalCancel(String appName, String id, boolean isReplication) { this.handleCancelation(appName, id, isReplication); return super.internalCancel(appName, id, isReplication); } private void handleCancelation(String appName, String id, boolean isReplication) { this.log("cancel " + appName + ", serverId " + id + ", isReplication " + isReplication); this.publishEvent(new EurekaInstanceCanceledEvent(this, appName, id, isReplication)); } private void handleRegistration(InstanceInfo info, int leaseDuration, boolean isReplication) { this.log("register " + info.getAppName() + ", vip " + info.getVIPAddress() + ", leaseDuration " + leaseDuration + ", isReplication " + isReplication); this.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); } private void log(String message) { if (log.isDebugEnabled()) { log.debug(message); } } private void publishEvent(ApplicationEvent applicationEvent) { this.ctxt.publishEvent(applicationEvent); } private int resolveInstanceLeaseDuration(InstanceInfo info) { int leaseDuration = 90; if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) { leaseDuration = info.getLeaseInfo().getDurationInSecs(); } return leaseDuration; }}差不多能用上的就这几个类了,这5个server端事件在这几个类中都能找到。
知道了事件名,要监听就很简单了
package com.tianyalei.server;import com.netflix.appinfo.InstanceInfo;import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent;import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent;import org.springframework.cloud.netflix.eureka.server.event.EurekaServerStartedEvent;import org.springframework.context.event.EventListener;import org.springframework.stereotype.Component;/** * Created by wuweifeng on 2017/10/10. */@Componentpublic class EurekaStateChangeListener { @EventListener public void listen(EurekaInstanceCanceledEvent eurekaInstanceCanceledEvent) { //服务断线事件 String appName = eurekaInstanceCanceledEvent.getAppName(); String serverId = eurekaInstanceCanceledEvent.getServerId(); System.out.println(appName); System.out.println(serverId); } @EventListener public void listen(EurekaInstanceRegisteredEvent event) { InstanceInfo instanceInfo = event.getInstanceInfo(); System.out.println(instanceInfo); } @EventListener public void listen(EurekaInstanceRenewedEvent event) { event.getAppName(); event.getServerId(); } @EventListener public void listen(EurekaRegistryAvailableEvent event) { } @EventListener public void listen(EurekaServerStartedEvent event) { //Server启动 }}在server项目里加上这个监听类,然后在各个事件被触发时就能在这里监听并处理了。
譬如我启动一个client
在这里就能看到新注册的client的各项详细信息。
然后我再关掉client
可以看到挂掉的client的appName,serverId等信息。那么我们就可以在这里做一些处理,譬如邮件通知管理员,某某服务挂掉了。
阅读全文
0 0
- eureka监听各服务状态,下线、重连等,并做相应的处理
- Eureka下线服务
- SpringCloud服务如何在Eureka安全优雅的下线
- 利用eureka REST接口,强制服务下线
- Cmenu类方法判断弹出按钮选中状态并做相应处理
- Android监听程序处于INACTIVITY(未操作状态)时间并作出相应的操作
- 实时监听输入框的值变化的时候,做相应处理
- 怎么从键盘接收按下来的控制键,并做相应的处理。
- 将拍摄的照片写入相册,并拿到相关参数做相应的处理
- 用批处理或PowerShell监控系统服务状态并做及时处理
- Eureka的服务认证
- Eureka的服务集群
- 一秒学会安卓tcp基于netty4.x心跳,断线重连,状态监听
- 如何做加载状态的监听。
- Android监听网络状态变化,随着网络的变化做一些其他处理
- 【技术总结】监听接口返回的未登录(或其他)状态做统一处理
- Windows/Linux下Oracle监听日志过大无需重启数据库服务的处理方法
- IOS手势初步学习--监听相应的手势处理
- 计时器
- Log4J的详细描述和操作-Java
- 循环队列的应用——舞伴配对问题(数据结构 C语言)
- Java——基于JDK的几种加密方式
- Flex 学习之路之八 用户接口user interface 位置大小的设置
- eureka监听各服务状态,下线、重连等,并做相应的处理
- 2.消息中间件概述
- Python3 压缩与解压缩(zlib / gzip / bz2 / lzma / zipfile / tarfile)
- 网络间进程的通信--socket
- ZooKeeper的简单操作
- GKRidgedNoiseSource
- 周志华《机器学习》学习笔记2--模型评估与选择
- Web安全之权限攻击
- qt中的常见错误