【微服务】仿微服务式集成组件

一、背景及设计思路

现行多系统间http请求接口方式交互,于是就会产生如下问题:① url或uri需要用数据库或枚举存储,需要查库或者拼接url; ② 系统服务地址都需要在项目中配置定义,没有统一管理,修改添加代码成本大。

以我们项目为例,url地址作为param在数据库中存储,不同环境url的服务地址各不相同,这样给数据库脚本维护及上线带来潜在风险。同样,在修改uri或服务器迁移(如果域名解析的话,就没有此问题),就需要对个环境做param清洗,增加开发工作量。

在尽量对原有项目较少改动的前提下,设计思路如下:

1、针对各项目散落的系统服务地址问题,方法就是将URL地址从系统抽离。

      将原先URL地址拆分为“服务地址+uri”,按照各profile地址,将服务器地址同一管理起来,作为父pom供各系统继承。此处还将各环境公用的环境配置信息都抽到父pom中,诸如:redis地址、zk地址、kafka地址等。

2、针对uri问题    分两步解决,① 存储:之所以选择枚举而不是数据库存储,主要是考虑到uri修改频率较低。另外,如果用数据库存储,最好还是同缓存共同管理uri,以此减少与数据库交互的次数。

      ② url拼接:首先根据各系统提供的api接口,分类将uri存到对应枚举。系统启动时,将各请求url对应的code值初始化到内存,并暴露出接口供系统调用。

  将上述代码实现封装到 client.jar 中,作为集成组件,系统调用对应接口即可。

二、实现

1、父类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

2、项目依赖 父pom文件

  同时定义一个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}"
  }
]

3、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) {
    //同上  
    }
}

3、后记

至此,一个仿微服务的组件就基本搭出框架了。其实,本质上这个并不是微服务,系统间请求仍由HTTP完成,只不过是请求地址由Client封装提供,以此管理多而复杂的请求地址。

目前比较主流的微服务框架有:Spring Cloud, Dubbo。

Dubbo 本人已经有写了一个简单的例子,具体原理还没有分析。

Spring Cloud 后续接触了再做总结。

原文地址:https://www.cnblogs.com/liuxs13/p/9298291.html