Implementing remote monitoring in spring

   In recent projects, a cluster is required, and the cache cluster is implemented by itself. After the cache changes, a message needs to be sent to each node to update the cache. So I made a remote monitoring function. The rmi protocol is used for remote monitoring, and the active nodes are dynamically queried before the event is released. After the event is released, it will be monitored by the listener on the active node. Above code
1. Define event and listener
public class  BaseEvent  extends EventObject {


	private static final long serialVersionUID = 1L;
	
	
	/** System time when the event happened */
	private final long timestamp;
	

	public BaseEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
		
	}
	
	/**
	 * Return the system time in milliseconds when the event happened.
	 */
	public final long getTimestamp() {
		return this.timestamp;
	}
}

public interface EventLisenter<T extends BaseEvent>{

	/**
	 * event handling
	 * @param baseEvent
	 */
	void onEvent(T t);
}

2. Define the remote monitoring configuration
public  class RemoteLisenter{
	
	private  Class  eventClass;
	
	private Class serviceInterface;
	
	private String serviceName;
	
	private String  registryPort;

	public Class getServiceInterface() {
		return serviceInterface;
	}

	public void setServiceInterface(Class serviceInterface) {
		this.serviceInterface = serviceInterface;
	}

	public String getServiceName() {
		return serviceName;
	}

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
	}


Monitoring management class for event registration, updating remote monitoring, and publishing events
public class RemoteLisenterConfig {

	private List<RemoteLisenter> remoteLisenters =new ArrayList<RemoteLisenter>();
	
	
	public List<RemoteLisenter> getRemoteLisenters() {
		return remoteLisenters;
	}


	public void setRemoteLisenters(List<RemoteLisenter> remoteLisenters) {
		this.remoteLisenters = remoteLisenters;
	}

}


@Service
public class ListennerManagement {

	
	protected Logger logger = Logger.getLogger(getClass());

	
	@Autowired
	private HeartbeatService heartbeatService;
	
	
	@Autowired
	RemoteLisenterConfig remoteLisenterConfig;
	
	
	
	

	/**
	 * Local monitoring
	 */
	private  Map<String, List<EventLisenter>> localListeners = new LinkedHashMap<String, List<EventLisenter>>();
	
	/**
	 * Remote monitoring
	 */
	private  Map<String, List<EventLisenter>> remoteListeners = new LinkedHashMap<String, List<EventLisenter>>();

	

	/**
	 * Scan all beans and perform event monitoring for team local events
	 *
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public  void registryListener(ApplicationContext  ctx) throws Exception {
		// Get all listeners in the container
		Map<String, EventLisenter> beans = ctx
				.getBeansOfType(EventLisenter.class);
		if (beans == null || beans.size() == 0) {
			return;
		}
		Collection<EventLisenter> list = beans.values();
		for (EventLisenter listener : list) {
			Class listenercls = AopTargetUtils.getTarget(listener).getClass();
			Class eventCls = GenericTypeResolver.resolveTypeArgument(
					listenercls, EventLisenter.class);

			try {
				if (localListeners.containsKey(eventCls.getName())) {
					localListeners.get(eventCls.getName()).add(listener);
				} else {
					List<EventLisenter> l = new ArrayList<EventLisenter>();
					l.add(listener);
					localListeners.put(eventCls.getName(), l);
				}
			} catch (Exception e) {
				throw new Exception("Error initializing event listener: ", e);
			}
		}

	}

	
	 private void refreshRemoteListeners(){
		//Query the IP of the cluster server (queried from the database configuration here)
		List<String> ipList=heartbeatService.getAliveHostsExcludeSelf();
		List<RemoteLisenter>  RemoteLisenterList=remoteLisenterConfig.getRemoteLisenters();
		remoteListeners = new LinkedHashMap<String, List<EventLisenter>>();
		if(RemoteLisenterList!=null){
			for (RemoteLisenter remoteLisenter : RemoteLisenterList) {
				
				String eventClsName=remoteLisenter.getEventClass().getName();
				Class listenerCls=remoteLisenter.getServiceInterface();
				String port=remoteLisenter.getRegistryPort();
				String serviceName=remoteLisenter.getServiceName();
				if(ipList!=null){
					for (String ip : ipList) {
						EhCacheService ehCacheService=null;
						EventLisenter listener = buildRemotListener(listenerCls, port,serviceName, ip);
						
						if(listener!=null){
							if (remoteListeners.containsKey(eventClsName)) {
								remoteListeners.get(eventClsName).add(listener);
							} else {
								List<EventLisenter> l = new ArrayList<EventLisenter>();
								l.add(listener);
								remoteListeners.put(eventClsName, l);
							}
						}
					}
				}
			
		}
			
			
			
		}
	}


	private EventLisenter buildRemotListener(Class listenerCls, String port,
			String serviceName, String ip) {
		
		try {
			RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
			rmiProxyFactoryBean.setServiceInterface(listenerCls);
			rmiProxyFactoryBean.setServiceUrl("rmi://"+ip+":"+port+"/"+serviceName);
			rmiProxyFactoryBean.afterPropertiesSet();
			
			if (rmiProxyFactoryBean.getObject() instanceof EventLisenter) {
				EventLisenter  listener=(EventLisenter)rmiProxyFactoryBean.getObject();
				return listener;
			}else{
				return null;
			}
		} catch (Exception e) {
			logger.error("Get remote listener bean error [listenerClass="+listenerCls+";port="+port+";ip="+ip+";serviceName="+serviceName+"]", e);
			return null;
		}
		
		
		

		
	}
	
	
	/**
	 * Post event
	 *
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public  void publishEvent(BaseEvent event)  {
		//local monitoring
		List<EventLisenter> localList = localListeners.get(event.getClass().getName());
		if (localList != null) {
			for (EventLisenter listener : localList) {
				try {
					listener.onEvent(event);
				} catch (Exception e) {
					logger.error(e.getMessage());
				}
			}
		}
		
		//Remote monitoring
		Class eventClass=event.getClass();
		if(needRemoteListenre(eventClass)){
			// refresh the remote listener
			refreshRemoteListeners();
			
			List<EventLisenter> remoteList = remoteListeners.get(event.getClass().getName());
			if (remoteList != null) {
				for (EventLisenter listener : remoteList) {
					try {
						listener.onEvent(event);
					} catch (Exception e) {
						logger.error(e.getMessage());
					}
				}
			}
		}
	}


    /**
     * Determine whether this event needs to be monitored remotely
     * @param eventClass
     * @return
     */
	private boolean needRemoteListenre(Class eventClass) {
		
		List<RemoteLisenter>  RemoteLisenterList=remoteLisenterConfig.getRemoteLisenters();
		if(RemoteLisenterList!=null){
			for (RemoteLisenter remoteLisenter : RemoteLisenterList) {			
			     Class eventCls=remoteLisenter.getEventClass();
			     if(eventCls.equals(eventCls))
			    	 return true;
			}
		}
		return false;	
			
	}


	public Map<String, List<EventLisenter>> getLocalListeners() {
		return localListeners;
	}


	public Map<String, List<EventLisenter>> getRemoteListeners() {
		return remoteListeners;
	}
	


configuration file
<!-- Configure remote monitoring configuration object-->
	<bean id="remoteLisenterConfig"  class="com.ejintai.cbs_policy_registry.base.event.RemoteLisenterConfig">
	  <property name="remoteLisenters">
	     <list>
	     <bean id="remoteLisenter1"  class="com.ejintai.cbs_policy_registry.base.event.RemoteLisenter">
	          <property name="eventClass"      value="com.ejintai.cbs_policy_registry.base.event.biz.EhCacheUpdateEvent" />  
	          <property name="serviceName"         value="ehCacheUpdateEventListener" />  
              <property name="serviceInterface"    value="com.ejintai.cbs_policy_registry.base.event.EventLisenter"/>  
      		  <property name="registryPort"        value="${rmi.port}"/>  
	      </bean>
	     </list>
	  </property>
	</bean>

 <bean id="remoteEhCacheUpdateEventListener" class="org.springframework.remoting.rmi.RmiServiceExporter" >  
        <property name="serviceName"         value="ehCacheUpdateEventListener" />  
        <property name="service"             ref="ehCacheUpdateEventListener"/>  
        <property name="serviceInterface"    value="com.ejintai.cbs_policy_registry.base.event.EventLisenter"/>  
        <property name="registryPort"        value="${rmi.port}"/>  
    </bean>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326350305&siteId=291194637