diff --git a/doc/分布式架构图.vsdx b/doc/分布式架构图.vsdx index d9b097fda..5d7b378e0 100644 Binary files a/doc/分布式架构图.vsdx and b/doc/分布式架构图.vsdx differ diff --git a/redkale.html b/redkale.html index 1e38e6012..9da319fb2 100644 --- a/redkale.html +++ b/redkale.html @@ -263,7 +263,6 @@ <property name="value-type" value="java.lang.Integer"/> </service> </services> - <servlets autoload="true" /> </server> </application>

      通知模块NotifyService服务群中各个进程的配置相同,配置如下:

@@ -293,7 +292,6 @@ <!-- 存在DataSource必须配置DataSourceService --> <service name="demodb" value="org.redkale.service.DataSourceService" groups="NOTIFY_SERVICE"/> </services> - <servlets autoload="true" /> </server> </application>

      帖子模块ForumService服务群中各个进程的配置相同,配置如下:

@@ -321,12 +319,113 @@ <!-- 存在DataSource必须配置DataSourceService --> <service name="demodb" value="org.redkale.service.DataSourceService" groups="FORUM_SERVICE"/> </services> - <servlets autoload="true" /> </server> </application> -

      由这个范例可以看出,RedKale提供了非常强大的架构,集中式到微服务架构不需要增加修改一行代码即可随意切换,复杂的系统都可以如小系统般快速地开发出来。
+
+

      5、API网关式部署

+

      随着用户量到了上千万时,一个UserService的服务进程是无法提供全部用户服务。 因此可以考虑按用户段进行分布式部署。将192.168.50.110、192.168.50.111上的UserService服务改成网关式的服务。下面是以 Service本地模式介绍中的UserService 为范例进行编写:

+
@ResourceType({UserService.class})
+public class UserServiceGateWay extends UserService {
+
+    @Resource(name = "userservice_reg")
+    private UserService regUserService;  //只用于注册的服务节点
+
+    @Resource(name = "userservice_mob")
+    private UserService mobUserService;  //只用于查询手机号码对应的userid的服务节点
+
+    @Resource(name = "userservice_node01")
+    private UserService userService01;  //userid小于2000000的用户的服务节点
+
+    @Resource(name = "userservice_node02")
+    private UserService userService02;  //userid小于4000000的用户的服务节点
+
+    @Resource(name = "userservice_node03")
+    private UserService userService03;  //userid小于6000000的用户的服务节点
+
+    @Resource(name = "userservice_node04")
+    private UserService userService04;  //userid大于6000000的用户的服务节点
+
+    private UserService getService(int userid) {
+        if (userid <= 200_0000) return userService01;
+        if (userid <= 400_0000) return userService02;
+        if (userid <= 600_0000) return userService03;
+        return userService04;
+    }
+
+    @Override
+    public UserInfo findUserInfo(int userid) {
+        return this.getService(userid).findUserInfo(userid);
+    }
+
+    @Override
+    public RetResult<UserInfo> login(LoginBean bean) { //手机号码用long存储,0表示无手机号码
+        int userid = mobUserService.findUserid(bean.getMobile());
+        if (userid < 1) return new RetResult<>(10001, "not found mobile " + bean.getMobile());
+        return this.getService(userid).login(bean);
+    }
+
+    @Override
+    public void register(UserInfo user) {
+        regUserService.register(user); //会生成userid
+        this.getService(user.getUserid()).putUserInfo(user);
+    }
+
+    @Override
+    public UserInfo updateUsername(int userid, String username) {
+        return this.getService(userid).updateUsername(userid, username);
+    }
+}
+                
+

      从代码看出,UserServiceGateWay继承了UserService, 确保了UserService对外的服务接口不变,上面代码是用户量在600-800万之间的写法,通过简单的用户ID分段,根据不同用户ID调不同的服务节点。

+

+

      如上图,网关下的UserService部署分三类: userservice_reg只用于注册用户;userservice_mob提供查询手机号码与用户ID间的关系的服务;userservice_node按用户段提供已有用户的服务。且每个UserService的实例在UserServiceGateWay都是远程模式。每种类型可以部署多个节点(为了结构图简单,上图每个类型只部署一个节点)。UserServiceGateWay(192.168.50.110、192.168.50.111)的配置如下:

+
<application port="5050">  
+    <resources>	
+        <group name="USER_SERVICE_REG">
+            <node addr="192.168.70.110" port="7070"/>
+        </group>
+        <group name="USER_SERVICE_MOB">
+            <node addr="192.168.70.150" port="7070"/>
+        </group>
+        <group name="USER_SERVICE_NODE01">
+            <node addr="192.168.70.201" port="7070"/>
+        </group>
+        <group name="USER_SERVICE_NODE02">
+            <node addr="192.168.70.202" port="7070"/>
+        </group>
+        <group name="USER_SERVICE_NODE03">
+            <node addr="192.168.70.203" port="7070"/>
+        </group>
+        <group name="USER_SERVICE_NODE04">
+            <node addr="192.168.70.204" port="7070"/>
+        </group>
+        
+        <group name="USER_SERVICE">
+            <node addr="192.168.50.110" port="7070"/>
+            <node addr="192.168.50.111" port="7070"/>
+        </group>        
+    </resources>
+
+    <!-- SNCP 监听 Server -->
+    <server protocol="SNCP" port="7070"> 
+        <services autoload="true">	
+            <!-- 配置UserService网关 -->
+            <service name="" value="org.redkale.demo.UserServiceGateWay" groups="USER_SERVICE"/>
+            <!-- 配置UserService分段节点 -->
+            <service name="userservice_reg" value="org.redkale.demo.UserService" groups="USER_SERVICE_REG"/>
+            <service name="userservice_mob" value="org.redkale.demo.UserService" groups="USER_SERVICE_MOB"/>
+            <service name="userservice_node01" value="org.redkale.demo.UserService" groups="USER_SERVICE_NODE01"/>
+            <service name="userservice_node02" value="org.redkale.demo.UserService" groups="USER_SERVICE_NODE02"/>
+            <service name="userservice_node03" value="org.redkale.demo.UserService" groups="USER_SERVICE_NODE03"/>
+            <service name="userservice_node04" value="org.redkale.demo.UserService" groups="USER_SERVICE_NODE03"/>
+        </services>
+    </server> 
+</application>
+
+

      由以上几种部署方式的范例可以看出,RedKale提供了非常强大的架构,集中式到微服务架构不需要增加修改一行代码即可随意切换,即使网关式部署也只是新增很少的代码就可切换,且不影响其他服务。复杂的系统都可以如小系统般快速地开发出来。
      为了降低接入层与业务层代码的耦合, 可以将Service分接口与实现两个类,接入层只加载接口包、业务层使用实现包。

+

appplication.xml 配置说明

<?xml version="1.0" encoding="UTF-8"?>