【微服務】仿微服務式集成組件

1、背景及設計思路

現行多系統間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

2、實現

一、父類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>
View Code

 

二、項目依賴 父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 後續接觸了再作總結。

相關文章
相關標籤/搜索