spider RPC开发指南
请访问https://git.oschina.net/zhjh256/io-spider获取最新更新。
协议与兼容性
spider使用java语言开发,使用Spring作为IoC容器,采用TCP/IP协议,在此基础上,结合SaaS系统模式的特性进行针对性和重点设计,以更加灵活和高效的满足多租户系统、高可用、分布式部署的要求。
采用JSON作为序列化机制,后续版本可能会考虑支持protobuf(java/c++/c#均有类库支持)。
为了最大化性能以及稳定性,spider基于Sun JDK1.8进行编译并应避免使用deprecated特性。
为了尽可能的适应各环境以及互联网应用,spider应能至少运行于tomcat/jboss应用服务器下。
部署模式
任何时候,Spider可运行于中心化管理模式或独立管理模式之一。
中心化管理模式:中心化模式要求必须启用服务中心。对于有几十个运行节点的大规模部署而言,通常增加或者减少一个节点/拆分服务需要进行的配置文件数量会很多,通常位于新增节点上游的各节点都需要修改相应的路由和对应的服务器参数。采用中心化管理模式,只需要登录服务中心修改相关配置即可,节点的变化会自动推送给相应的上游节点。运行于中心化管理模式时,可在服务中心查看整个平台中所有节点的健康状态、各服务的TPS、响应时间等。
独立管理模式:独立管理模式无需启用服务中心。当节点数量较少,比如整个平台不超过十个节点时,采用独立模式通常会比中心化管理模式更简单。运行于独立管理模式时,可通过spider提供的restful api查看当前节点的运行状态。
服务标识
Spider支持两种服务发布注解。
spider定义了两个自定义注解用于标识spider服务。
服务模块
@Retention(RetentionPolicy.RUNTIME) public @interface ServiceModule { String subSystemId() default "0"; }
@ServiceModule只是一个类注解,具有该注解的接口将被认为是spider服务接口类,定义在该接口中是被标识为spider服务的必要条件。
服务接口
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Service { String serviceId(); // 服务编号,8位ASCII字符,其中00000000-00000099为spider内部保留,00000100-00000199为服务中心保留 String desc(); //服务描述 int timeout() default 0; //超时时间,单位毫秒 boolean needLog() default false; //设置是否记录日志 int broadcast() default 0; //设置该请求是否广播,0:不广播;1:广播但无需相应;2:广播并响应 }
@Service是一个方法注解,其包含三个属性,分别用于设置spider服务号,spider服务描述,spider服务超时时间。其中超时时间可选,默认为spider.xml中设置的超时时间,如果spider.xml中未定义,则默认为300秒。
只有定义在由@ServiceModule注解的接口中由@Service注解的方法才会被标识为spider服务,正确发布后,该接口可用于提供服务或者代理调用远程服务。
对于broadcast=2的服务,其返回值必须包装在com.ld.net.spider.pojo.BroadcastResult的data属性中,具体见该类的javadoc说明。
环境变量
spider有一些环境变量用于控制相关选项,目前有下列可设置的环境变量,如下所示:
l SPIDER_LOG,默认/tmp/spider/stat/${nodeName}
l SPIDER_HOME,默认/usr/local/spider/${nodeName}
l SPIDER_CONFIG,指定spider.xml启动文件,默认classpath:spider.xml,见配置文件一节。
配置文件
参考配置文件一节。
服务发布与代理
服务发布:spider.localService插件下的serviceExportPackage元素定义了spider节点作为服务器时自动对外发布的spider服务的包路径,以;或,分隔。只要服务端在该参数上设置了相关路径,java客户端只要在serviceProxyPackage参数上设置对应路径就可以直接通过@Autowired依赖注入方式调用远程服务端包下提供的相应服务。
服务代理:对于java客户端而言,spider提供了自动代理功能,开发者可像调用本地Spring服务一样调用远程服务器上的spider服务,开发者只需要在spider.localService插件下的serviceExportPackage元素上定义需要自动代理的spider服务的包路径,以;或,分隔。对于非java客户端比如C#或C++客户端而言,开发者需要调用对应的SDK Client。
发布的服务和代理的服务不能有交叉。如果一个服务既需要在本地处理,又需要spider代理转发给下游服务器,则配置在发布列表。此时这些服务无法通过用户编程来远程调用。通常这些服务是用于特殊目的,且被标记为broadcast。
PS:从技术上来说,只要客户端和服务端同一个服务的方法签名和服务号相同就能够调用(也就是方法名无关),不过不建议这么做,在将来的版本中也可能会要求完全匹配。
还需要注意的是,如果某个spider节点希望作为NB的角色,在serviceExportPackage配置了发布路径,同时又包含了某个服务的实现,如果该服务的路由条目被解析到本地处理,则该服务会在该NB节点被处理,而不会继续往后转发,这一点需要注意。所以,对于作为NB的角色,建议除了广播的服务,不要配置在serviceExportPackage下。
各种数据类型支持情况
spider当前版本支持除byte[]外基本上所有类型的数据类型,包括泛型对象。
服务接口定义要求
综合考虑灵活性,性能,开发效率,建议服务参数和返回值均采用对象(现有的RPC框架基本都采用这种模式,比如gRPC,ICE),同时参数继承SpiderBizHead类(其中包含了设置动态路由等相关信息)。如下所示:
入参DTO:
public class ServiceReq extends SpiderBizHead /*如果无需动态路由功能,则不必继承SpiderBizHead*/ {
}
服务签名:
@ServiceModule()
public interface DemoService {
@Service()
public ServiceResp addServer(ServerReq req);
}
还要考虑C++以及其他在用编程语言实现动态代理的简易性。
对于C#,可参考System.Runtime.Remoting.Proxies.RealProxy类实现。