ServerApplicationService - minbox-projects/message-pipe GitHub Wiki

消息管道服务端(Server)目前集成了两种启动服务监听的方式,分别是:NacosGrpc

了解 @EnableMessagePipeServer

无论我们使用哪一种的方式来启动服务监听,都需要通过@EnableMessagePipeServer注解进行配置,而该注解都进行了什么工作呢?

我们可以来查看下该注解的源码,@EnableMessagePipeServer注解源码如下所示:

/**
 * Enable message pipe server
 * <p>
 * Register the internal configuration classes required by the server to spring ioc through @import annotation
 *
 * @author 恒宇少年
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({MessagePipeServerImportBeanDefinitionRegistrar.class, ServerApplicationServiceSelector.class})
public @interface EnableMessagePipeServer {
    /**
     * Configure the way to pull the client
     *
     * @return {@link ServerServiceType} instance
     * @see org.minbox.framework.message.pipe.client.registrar.RegistrarService
     * @see org.minbox.framework.message.pipe.client.registrar.support.GRpcRegistrarService
     * @see org.minbox.framework.message.pipe.client.registrar.support.NacosRegistrarService
     */
    ServerServiceType serverType() default ServerServiceType.GRPC;
}

@EnableMessagePipeServer注解上可以看到添加了@Import引入配置,其中一个则是选择使用具体哪一种方式来启动服务的配置类,类名为:ServerApplicationServiceSelector,它实现了ImportSelector接口。

ServerApplicationServiceSelector内会根据ServerServiceType配置的值来进行选择实例化不同的ServerApplicationService

  • ServerServiceType.GRPC 会对应实例化 GRpcServerApplicationService
  • ServerServiceType.NACOS 会对应实例化 NacosServerApplicationService

Nacos 方式

Nacos的方式并不是在本地启动一个指定端口号的服务监听,而是通过订阅(subscribe)NamingService的服务列表变动监听来实现服务端本地缓存的客户端列表与Nacos Server服务列表实现实时同步。

启用Nacos服务监听

@Configuration
@EnableMessagePipeServer(serverType = ServerServiceType.NACOS)
public class MessagePipeServerConfiguration {
  // ...
}

配置NamingService

既然需要使用Nacos方式来读取客户端服务列表,而且上面也提到了采用的订阅的方式来获取客户端服务列表,那么我们需要在项目中实例化NamingService实例,如下所示:

/**
 * 配置{@link NamingService}服务实例
 *
 * @return The {@link NamingService} instance
 * @throws NacosException
 */
@Bean
public NamingService namingService() throws NacosException {
    Properties properties = new Properties();
    properties.put(PropertyKeyConst.USERNAME, "nacos");
    properties.put(PropertyKeyConst.PASSWORD, "nacos");
    // 免费开放Nacos服务,详情查看:https://blog.yuqiyu.com/open-nacos-server.html
    properties.put(PropertyKeyConst.SERVER_ADDR, "open.nacos.yuqiyu.com:80");
    return NacosFactory.createNamingService(properties);
}

Grpc 方式

Grpc是由Google开源的一款RPC服务框架。

服务端集成Grpc的主要目的是实现心跳检查服务注册消息分发等功能,因此我们如果采用GRPC的方式启动服务端时会对应的启动一个服务监听,而这个监听是服务端(Server)与客户端(Client)之间通信的桥梁。

启用 Grpc 服务监听

@Configuration
@EnableMessagePipeServer(serverType = ServerServiceType.GRPC)
public class MessagePipeServerConfiguration {
  // ...
}

服务注册

客户端启动后会通过配置的服务端地址以及端口号进行自动注册服务,而注册的逻辑则在GRpcServerApplicationService#register方法内,该方法内只是为客户端生成唯一的ID以及缓存客户端的基本信息(IP、Port)等。

真正维护客户端服务状态的逻辑则是通过发布ServiceEvent事件的方式交由ClientServiceDiscovery进行统一调度处理。

// Publish ServiceEvent
ServiceEvent serviceEvent = new ServiceEvent(this, ServiceEventType.REGISTER, Arrays.asList(client));
applicationEventPublisher.publishEvent(serviceEvent);

心跳检查

心跳检查的功能主要是为了分辨客户端是否健康,如果客户端长时间不进行上报心跳,则会被修改为离线、过期的状态,修改后就不会被作为分发消息的对象了。

服务端接收到心跳后同样会发布ServiceEvent服务事件,来告知ClientServiceDiscovery进行维护该客户端的状态。

// Publish heart beat event
ServiceEvent serviceEvent = new ServiceEvent(this, ServiceEventType.HEART_BEAT, Arrays.asList(client));
applicationEventPublisher.publishEvent(serviceEvent);