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類實現。