現行多系統間http請求接口方式交互,因而就會產生以下問題:① url或uri須要用數據庫或枚舉存儲,須要查庫或者拼接url; ② 系統服務地址都須要在項目中配置定義,沒有統一管理,修改添加代碼成本大。java
以咱們項目爲例,url地址做爲param在數據庫中存儲,不一樣環境url的服務地址各不相同,這樣給數據庫腳本維護及上線帶來潛在風險。一樣,在修改uri或服務器遷移(若是域名解析的話,就沒有此問題),就須要對個環境作param清洗,增長開發工做量。redis
在儘可能對原有項目較少改動的前提下,設計思路以下:數據庫
一、針對各項目散落的系統服務地址問題,方法就是將URL地址從系統抽離。apache
將原先URL地址拆分爲「服務地址+uri」,按照各profile地址,將服務器地址同一管理起來,做爲父pom供各系統繼承。此處還將各環境公用的環境配置信息都抽到父pom中,諸如:redis地址、zk地址、kafka地址等。json
二、針對uri問題 分兩步解決,① 存儲:之因此選擇枚舉而不是數據庫存儲,主要是考慮到uri修改頻率較低。另外,若是用數據庫存儲,最好仍是同緩存共同管理uri,以此減小與數據庫交互的次數。api
② url拼接:首先根據各系統提供的api接口,分類將uri存到對應枚舉。系統啓動時,將各請求url對應的code值初始化到內存,並暴露出接口供系統調用。緩存
將上述代碼實現封裝到 client.jar 中,做爲集成組件,系統調用對應接口便可。tomcat
一、父類pom文件,很簡單沒啥說的,能夠看到其中除了地址還定義了 redis地址,kafka開關,祕鑰等信息。服務器
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vegHunter</groupId> <artifactId>common-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>System Starter Parent</name> <description>Parent pom providing dependency and plugin management for applications of any system</description> <properties> <java.version>1.7</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> <!-- micro service name --> <micro.service.name>mservice</micro.service.name> <kafka.used.flag>closed</kafka.used.flag> <!-- The deployment address of all micro services --> <!-- 默認地址,若又不同,在profile裏重寫覆蓋便可 --> <server.url.serviceA>http://a.vegHunter.com</server.url.serviceA> <server.url.serviceB>http://b.vegHunter.com</server.url.serviceB> <server.url.serviceC>http://c.vegHunter.com</server.url.serviceC> <server.local.url.serviceA></server.local.url.serviceA> <server.local.url.serviceB></server.local.url.serviceB> <server.local.url.serviceC></server.local.url.serviceC> </properties> <profiles> <!-- 開發 --> <profile> <id>dev</id> <properties> <deploy.profile>dev</deploy.profile> <kafka.used.flag>closed</kafka.used.flag> <!-- jedis --> <JedisPool.host>10.10.10.100</JedisPool.host> <JedisPool.port>6381</JedisPool.port> <JedisPool.password>redis6381</JedisPool.password> <JedisPool.database>1</JedisPool.database> <!-- The deployment address of all micro services --> <!-- 沒有定義就是用默認的 --> <!-- 加簽祕鑰--> <params.http.securityCode>devsalt1</params.http.securityCode> </properties> </profile> <!-- 生產 --> <profile> <id>pro</id> <properties> <deploy.profile>pro</deploy.profile> <kafka.used.flag>closed</kafka.used.flag> <!-- jedis --> <JedisPool.host>10.10.10.101</JedisPool.host> <JedisPool.port>6381</JedisPool.port> <JedisPool.password>redis6381</JedisPool.password> <JedisPool.database>2</JedisPool.database> <!-- The deployment address of all micro services --> <server.url.serviceA>http://pro-a.veghunter.com</server.url.serviceA> <server.url.serviceB>http://pro-b.vegHunter.com</server.url.serviceB> <server.url.serviceC>http://pro-c.vegHunter.com</server.url.serviceC> <!-- The deployment local address of all micro services --> <server.local.url.serviceA>http://pro-local-a.vegHunter.com</server.local.url.serviceA> <server.local.url.serviceB>http://pro-local-b.vegHunter.com</server.local.url.serviceB> <server.local.url.serviceC>https://pro-local-c.vegHunter.com</server.local.url.serviceC> <params.http.securityCode>prosalt1</params.http.securityCode> </properties> </profile> </profiles> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>timestamp-property</id> <goals> <goal>timestamp-property</goal> </goals> <configuration> <name>build.time</name> <pattern>yyyyMMdd-HHmm</pattern> <locale>en</locale> <timeZone>Asia/Shanghai</timeZone> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <contextReloadable>false</contextReloadable> <uriEncoding>UTF-8</uriEncoding> <path>/</path> </configuration> </plugin> </plugins> </build> <dependencyManagement> <dependencies> ... 各類依賴 </dependencies> </dependencyManagement> </project>
二、項目依賴 父pom文件app
同時定義一個json文件,用於初始化各服務地址。
[
{
"name": "A",
"serverUrl": "${server.url.serviceA}",
"localServerUrl": "${server.local.url.serviceA}"
},
{
"name": "B",
"serverUrl": "${server.url.serviceB}",
"localServerUrl": "${server.local.url.serviceB}"
},
{
"name": "C",
"serverUrl": "${server.url.serviceC}",
"localServerUrl": "${server.local.url.serviceC}"
}
]
三、client.jar 中拼接url並提供接口
接下來寫一些僞代碼,主要看思路
定義全部服務的枚舉
public enum MicroServiceEnum { A("A","A系統"), B("B","B系統"), C("C","C系統") }
定義各服務對應的uri枚舉
public enum AMicroServiceEnum { AURI-1("/query/users","檢索用戶列表"), BURI-2("/editUser","修改用戶"), CURL-3("/addUser","添加用戶") }
初始化類(系統啓動時,初始化地址及uri信息到內存)
public class MicroServiceInitializer { private MicroServiceInitializer {super();} public static synchronized Map<String, MicroServiceInfo> init() { //1.遍歷系統定義的json格式,將各屬性賦值 //2.找到對應服務,遍歷服務對應的uri //3.將上述兩步組成serviceMap,key值爲服務code,value爲實體(包含服務地址,uri的map格式) //4.將封裝好的serviceMap放到內存 } }
拼接URL,提供接口
public class AMicroClientService { private final MicroServiceEnum enun = MicroServiceEnum.A; public static String getAUri1() { //1. 根據enun找到對應的服務對象 //2. 根據AUri1對應的code,從服務對象中的map找到服務對應的uri //3. 拼接返回 } public static String getAUri2(String code) { //同上 } public static String getAUri3(String code) { //同上 } }
至此,一個仿微服務的組件就基本搭出框架了。其實,本質上這個並非微服務,系統間請求仍由HTTP完成,只不過是請求地址由Client封裝提供,以此管理多而複雜的請求地址。
目前比較主流的微服務框架有:Spring Cloud, Dubbo。
Dubbo 本人已經有寫了一個簡單的例子,具體原理尚未分析。
Spring Cloud 後續接觸了再作總結。