706 lines
93 KiB
HTML
706 lines
93 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en-us">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Redkale(红菜苔)--基于Java 8全新的微服务开源框架 - Redkale官网</title>
|
||
<meta name="keywords" content="Redkale,redkale,java,微服务,架构"/>
|
||
<meta name="description" content="Redkale(红菜苔)是基于Java 8全新的微服务开源框架"/>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
|
||
</head>
|
||
<body>
|
||
<section class="page-header">
|
||
<a href="index.html" class="project-name">Redkale</a>
|
||
<h2 class="project-tagline"></h2>
|
||
<a href="redkale.html" class="btn">Redkale 入门</a>
|
||
<a href="convert.html" class="btn">Convert 组件</a>
|
||
<a href="service.html" class="btn">Service 组件</a>
|
||
<a href="source.html" class="btn">Source 组件</a>
|
||
<a href="net.html" class="btn">Net 组件</a>
|
||
<a href="watch.html" class="btn">Watch 组件</a>
|
||
<a href="articles.html" class="btn">技术文章</a>
|
||
<a href="code.html" class="btn">Java 源码</a>
|
||
</section>
|
||
|
||
<section class="main-content">
|
||
<h3><a id="redkale_start" class="anchor" href="#" aria-hidden="true"></a>Redkale 功能</h3>
|
||
|
||
<p> Redkale虽然不到1M大小,但是麻雀虽小五脏俱全。既可作为服务器使用,也可当工具包使用。作为独立的工具包提供以下功能:<br/>
|
||
1、convert包提供JSON的序列化和反序列化功能,类似Gson、Jackson。 <br/>
|
||
2、convert包提供Java对象二进制的序列化和反序列化功能,类似Protobuf。 <br/>
|
||
3、source包提供很简便的数据库操作功能,类似JPA、Hibernate。 <br/>
|
||
4、net包提供TCP/UDP服务功能, 类似Mina。 <br/>
|
||
5、net.http提供HTTP服务, 类似Tomcat、Netty。 <br/>
|
||
6、ResourceFactory提供轻量级的依赖注入功能, 类似Google Guice。 <br/>
|
||
</p>
|
||
|
||
<h3><a id="redkale_server" class="anchor" href="#" aria-hidden="true"></a>Redkale 服务器</h3>
|
||
<p> Redkale作为服务器的目录如下: <br/>
|
||
<b>bin</b> : 存放启动关闭脚本(start.sh、shutdown.sh、start.bat、shutdown.bat) <br/>
|
||
<b>conf</b> : 存放服务器所需配置文件:<br/>
|
||
<a href="#redkale_confxml">application.xml</a>: 服务配置文件 (必需);<br/>
|
||
logging.properties:日志配置文件 (可选); <br/>
|
||
persistence.xml:数据库配置文件 (可选);<br/>
|
||
<b>lib</b> : 存放服务所依赖的第三方包,redkale.jar 放在此处。 <br/>
|
||
<b>logs</b> : logging.properties 配置中默认的日志存放目录。<br/>
|
||
<b>root</b> : application.xml 配置中HTTP服务所需页面的默认根目录。 <br/>
|
||
</p>
|
||
|
||
<p> Redkale启动的流程如下:<br/>
|
||
1、加载 <a href="#redkale_confxml">application.xml</a> 并解析。 <br/>
|
||
2、初始化 <b><resources></b> 节点中的资源。 <br/>
|
||
3、解析所有的 <b><server></b> 节点。 <br/>
|
||
4、初始化并启动所有<b><server></b> 节点的Server服务 (优先加载SNCP协议的Server)。 <br/>
|
||
5、初始化单个Server: <br/>
|
||
5.1、扫描classpath加载所有可用的Service实现类(没有标记为@AutoLoad(<span style="color: #0000FF;">false</span>)的类)并实例化,然后相互依赖注入。 <br/>
|
||
5.2、Service实例在依赖注入过程中加载所需的DataSource、CacheSource资源。 <br/>
|
||
5.3、调用所有本地模式Service的init方法。 <br/>
|
||
5.4、扫描classpath加载所有可用的Servlet实现类(没有标记为@AutoLoad(<span style="color: #0000FF;">false</span>)的类)并实例化 (WebSocketServlet优先)。<br/>
|
||
5.5、给所有Servlet依赖注入所需的Service。 <br/>
|
||
5.6、调用所有Servlet的init方法。 <br/>
|
||
5.7、启动Server的服务监听。 <br/>
|
||
6、启动进程本身的监听服务。 <br/>
|
||
</p>
|
||
|
||
<h3><a id="redkale_dev" class="anchor" href="#" aria-hidden="true"></a>基于Redkale的开发与调试</h3>
|
||
<p> 基于Redkale创建一个Java应用程序工程(即使是Web项目也不要创建Java-Web工程),引用redkale.jar 并创建Redkale所需的几个目录和文件。一个普通的Web项目只需要编写业务层的Service和接入层的HttpServlet的代码。数据库DataSource通过配置文件进行设置。<br/>
|
||
编写完代码可以通过启动脚本进行调试, 也可以在IDE设置项目的主类为 org.redkale.boot.Application 或者工程内定义主类进行启动调试:
|
||
</p>
|
||
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Bootstrap</span> <span class="o">{</span>
|
||
|
||
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
|
||
<span class="n">org</span><span class="o">.</span><span class="na">redkale</span><span class="o">.</span><span class="na">boot</span><span class="o">.</span><span class="na">Application</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="n">args</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
<span class="o">}</span></pre></div>
|
||
<p> 若需要调试单个Service,可以通过 <b>Application.singleton</b> 方法进行调试: </p>
|
||
<div class="highlight"><pre> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
|
||
<span class="n">UserService</span> <span class="n">service</span> <span class="o">=</span> <b><span class="n">Application</span><span class="o">.</span><span class="na">singleton</span></b><span class="o">(</span><span class="n">UserService</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
|
||
<span class="n">LoginBean</span> <span class="n">bean</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">LoginBean</span><span class="o">();</span>
|
||
<span class="n">bean</span><span class="o">.</span><span class="na">setAccount</span><span class="o">(</span><span class="s">"myaccount"</span><span class="o">);</span>
|
||
<span class="n">bean</span><span class="o">.</span><span class="na">setPassword</span><span class="o">(</span><span class="s">"123456"</span><span class="o">);</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">service</span><span class="o">.</span><span class="na">login</span><span class="o">(</span><span class="n">bean</span><span class="o">));</span>
|
||
<span class="o">}</span></pre></div>
|
||
<p> Application.singleton 运行流程与通过bin脚本启动的流程基本一致,区别在于singleton运行时不会启动Server和Application自身的服务监听。Redkale提倡接入层(Servlet)与业务层(Service)分开,Service在代码上不能依赖于Servlet,因此调试Service自身逻辑时不需要启动接入层服务(类似WebSocket依赖Servlet的功能除外)。 </p>
|
||
|
||
<h3><a id="redkale_inject" class="anchor" href="#" aria-hidden="true"></a>Redkale的依赖注入</h3>
|
||
<p> Redkale内置的依赖注入实现很简单,只有三个类: javax.annotation.Resource、org.redkale.util.ResourceType、org.redkale.util.ResourceFactory,采用反射技术,由于依赖注入通常不会在频繁的操作中进行,因此性能要求不会很高。其中前两个是注解,ResourceFactory是主要操作类,主要提供注册和注入两个接口。ResourceFactory的依赖注入不仅提供其他依赖注入框架的常规功能,还能动态的自动更新通过inject注入的资源。</p>
|
||
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">AService</span> <span class="o">{</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"property.id"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">String</span> <span class="n">id</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"property.id"</span><span class="o">)</span> <span class="c1">//property.开头的资源名允许String自动转换成primitive数值类型</span>
|
||
<span class="kd">private</span> <span class="kt">int</span> <span class="n">intid</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"bigint"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">BigInteger</span> <span class="n">bigint</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"seqid"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="kt">int</span> <span class="n">seqid</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Resource</span>
|
||
<span class="kd">private</span> <span class="n">ResourceTest</span><span class="o">.</span><span class="na">BService</span> <span class="n">bservice</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="n">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
|
||
<span class="k">return</span> <span class="s">"{id:\""</span> <span class="o">+</span> <span class="n">id</span> <span class="o">+</span> <span class="s">"\", intid: "</span> <span class="o">+</span> <span class="n">intid</span> <span class="o">+</span> <span class="s">", bigint:"</span> <span class="o">+</span> <span class="n">bigint</span> <span class="o">+</span> <span class="s">"}"</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="cm">/** 以下省略getter setter方法 */</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">BService</span> <span class="o">{</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"property.id"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">String</span> <span class="n">id</span><span class="o">;</span>
|
||
|
||
<span class="nd">@Resource</span>
|
||
<span class="kd">private</span> <span class="n">AService</span> <span class="n">aservice</span><span class="o">;</span>
|
||
|
||
<span class="kd">private</span> <span class="n">String</span> <span class="n">name</span> <span class="o">=</span> <span class="s">""</span><span class="o">;</span>
|
||
|
||
<span class="nd">@java.beans.ConstructorProperties</span><span class="o">({</span><span class="s">"name"</span><span class="o">})</span>
|
||
<span class="kd">public</span> <span class="nf">BService</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="n">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
|
||
<span class="k">return</span> <span class="s">"{name:\""</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">"\", id: "</span> <span class="o">+</span> <span class="n">id</span> <span class="o">+</span> <span class="s">", aserivce:"</span> <span class="o">+</span> <span class="n">aservice</span> <span class="o">+</span> <span class="s">"}"</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="cm">/** 以下省略getter setter方法 */</span>
|
||
<span class="o">}</span>
|
||
|
||
|
||
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
|
||
<span class="n">ResourceFactory</span> <span class="n">factory</span> <span class="o">=</span> <span class="n">ResourceFactory</span><span class="o">.</span><span class="na">root</span><span class="o">();</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"property.id"</span><span class="o">,</span> <span class="s">"2345"</span><span class="o">);</span> <span class="c1">//注入String类型的property.id</span>
|
||
<span class="n">AService</span> <span class="n">aservice</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">AService</span><span class="o">();</span>
|
||
<span class="n">BService</span> <span class="n">bservice</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">BService</span><span class="o">(</span><span class="s">"eee"</span><span class="o">);</span>
|
||
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//放进Resource池内,默认的资源名name为""</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span> <span class="c1">//放进Resource池内,默认的资源名name为""</span>
|
||
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//给aservice注入id、bservice,bigint没有资源,所以为null</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span> <span class="c1">//给bservice注入id、aservice</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//输出结果为:{id:"2345", intid:2345, bigint:null, bservice:{name:eee}}</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span> <span class="c1">//输出结果为:{name:"eee", id:2345, aserivce:{id:"2345", intid:2345, bigint:null, bservice:{name:eee}}}</span>
|
||
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"seqid"</span><span class="o">,</span> <span class="mi">200</span><span class="o">);</span> <span class="c1">//放进Resource池内, 同时ResourceFactory会自动更新aservice的seqid值</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">factory</span><span class="o">.</span><span class="na">find</span><span class="o">(</span><span class="s">"seqid"</span><span class="o">,</span> <span class="kt">int</span><span class="o">.</span><span class="na">class</span><span class="o">));</span> <span class="c1">//输出结果为:200</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"bigint"</span><span class="o">,</span> <span class="k">new</span> <span class="nf">BigInteger</span><span class="o">(</span><span class="s">"66666"</span><span class="o">));</span> <span class="c1">//放进Resource池内, 同时ResourceFactory会自动更新aservice对象的bigint值 </span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//输出结果为:{id:"2345", intid:2345, bigint:66666, bservice:{name:eee}}可以看出seqid与bigint值都已自动更新</span>
|
||
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"property.id"</span><span class="o">,</span> <span class="s">"6789"</span><span class="o">);</span> <span class="c1">//更新Resource池内的id资源值, 同时ResourceFactory会自动更新aservice、bservice的id值</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//输出结果为:{id:"6789", intid:6789, bigint:66666, bservice:{name:eee}}</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span> <span class="c1">//输出结果为:{name:"eee", id:6789, aserivce:{id:"6789", intid:6789, bigint:66666, bservice:{name:eee}}}</span>
|
||
|
||
<span class="n">bservice</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">BService</span><span class="o">(</span><span class="s">"ffff"</span><span class="o">);</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span> <span class="c1">//更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象</span>
|
||
<span class="n">factory</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="n">bservice</span><span class="o">);</span>
|
||
<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">aservice</span><span class="o">);</span> <span class="c1">//输出结果为:{id:"6789", intid: 6789, bigint:66666, bservice:{name:ffff}}</span>
|
||
|
||
<span class="o">}</span></pre></div>
|
||
<p> 如上例,通过ResourceFactory.inject注入的对象都会自动更新资源的变化,若不想自动更新可以使用带boolean autoSync参数的register系列方法(autoSync传false)注册新资源。</p>
|
||
|
||
<h3><a id="redkale_deploy" class="anchor" href="#" aria-hidden="true"></a>Redkale 架构部署</h3>
|
||
<p> 通常一个系统会分为三层:接入层、业务层、数据层。对应到Redkale的组件是: Servlet、Service、Source。大部分系统提供的是HTTP服务,为了方便演示Redkale从集中式到分布式的变化,以一个简单的HTTP服务作为范例。<br/>
|
||
开发一个极简单的小论坛系统。包含三个模块: <br/>
|
||
用户模块 UserSerivice: 提供用户注册、登录、更新资料等功能, UserServlet作为接入层。<br/>
|
||
帖子模块 ForumSerivice: 提供看帖、发帖、删帖等功能, ForumServlet作为接入层。<br/>
|
||
通知模块 NotifySerivice: 提供用户操作、回帖等消息通知功能, NotifyWebSocket是WebSocket的Servlet, 且name为 <b>ws_notify</b>,作为接入层。 <br/>
|
||
其中数据源有: <br/>
|
||
DataSource: 在persistence.xml里配置的数据库Source的name为demodb ,三个模块都需要使用demodb。<br/>
|
||
CacheSource: 仅供UserSerivice用于存放session的缓存Service,name为 usersessions, 且session只存放用户ID( int 类型)。<br/>
|
||
</p>
|
||
<br/>
|
||
<p> <b>1、单点部署</b></p>
|
||
<p> 在早期用户量很少或者开发、调试环境中只需部署一个进程就可满足需求。 </p>
|
||
<p style="text-align: center;"><img src="images/distributeimg_1.png" alt=""/></p>
|
||
<p> 如上图,所有模块的HttpServlet、Service与Source数据库操作全部署在一起。 application.xml作简单的配置即可:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"HTTP"</span> <span class="na">port=</span><span class="s">"6060"</span> <span class="na">root=</span><span class="s">"root"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="nt">/></span>
|
||
<span class="nt"><servlets</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">/></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<br/>
|
||
|
||
<p> <b>2、多点部署</b></p>
|
||
<p> 在生产环境需要避免单点问题,一个服务一般会部署多套。在此做个简单的容灾部署,最前端部署一个nginx作反向代理和负载均衡服务器,后面部署两套系统。 </p>
|
||
<p style="text-align: center;"><img src="images/distributeimg_2.png" alt=""/></p>
|
||
<p> 如上图,两个进程间的Serivce都是本地模式,两者会通过SNCP服务保持数据同步,若DataSource开启了数据缓存也会自动同步。两套的配置文件相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- HTTP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"HTTP"</span> <span class="na">port=</span><span class="s">"6060"</span> <span class="na">root=</span><span class="s">"root"</span><span class="nt">></span>
|
||
<span class="c"><!-- 前端配置了nginx,需要配置才能获取客户端真实的IP地址 --></span>
|
||
<span class="nt"><request></span>
|
||
<span class="nt"><remoteaddr</span> <span class="na">value=</span><span class="s">"request.headers.X-RemoteAddress"</span><span class="nt">/></span>
|
||
<span class="nt"></request></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">groups=</span><span class="s">"ALL"</span><span class="nt">/></span>
|
||
<span class="nt"><servlets</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="nt">/></span>
|
||
<span class="nt"></server></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">groups=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="c"><!-- 有WebSocketServlet的服务必须配置WebSocketNodeService,且Redkale同时会自动创建一个同名(ws_notify)的 CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"ws_notify"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.WebSocketNodeService</b>"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存在DataSource必须配置DataSourceService --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"demodb"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.DataSourceService</b>"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存放用户HTTP session信息的CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"usersessions"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.CacheSourceService</b>"</span><span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"key-type"</span> <span class="na">value=</span><span class="s">"java.lang.String"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"value-type"</span> <span class="na">value=</span><span class="s">"java.lang.Integer"</span><span class="nt">/></span>
|
||
<span class="nt"></service></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<br/>
|
||
|
||
<p> <b>3、分层部署</b></p>
|
||
<p> 随着业务的复杂度增加,接入层与业务层混在一起会越来越难部署和维护,因此需要进行分层部署。 </p>
|
||
<p style="text-align: center;"><img src="images/distributeimg_3.png" alt=""/></p>
|
||
<p> 如上图,对HttpServlet与Service进行了分离。每个接入层的Service都是远程模式,业务层只需提供SNCP供远程调用。</p>
|
||
<p> 接入层中每个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- HTTP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"HTTP"</span> <span class="na">port=</span><span class="s">"6060"</span> <span class="na">root=</span><span class="s">"root"</span><span class="nt">></span>
|
||
<span class="c"><!-- 前端配置了nginx,需要配置才能获取客户端真实的IP地址 --></span>
|
||
<span class="nt"><request></span>
|
||
<span class="nt"><remoteaddr</span> <span class="na">value=</span><span class="s">"request.headers.X-RemoteAddress"</span><span class="nt">/></span>
|
||
<span class="nt"></request></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">groups=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="c"><!-- 有WebSocketServlet的服务必须配置WebSocketNodeService,且Redkale同时会自动创建一个同名(ws_notify)的 CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"ws_notify"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.WebSocketNodeService</b>"</span><span class="nt">/></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"><servlets</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="nt">/></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<p> 业务层中每个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">groups=</span><span class="s">"ALL"</span><span class="nt">></span>
|
||
<span class="c"><!-- 有WebSocketServlet的服务必须配置WebSocketNodeService,且Redkale同时会自动创建一个同名(ws_notify)的 CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"ws_notify"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.WebSocketNodeService</b>"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存在DataSource必须配置DataSourceService --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"demodb"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.DataSourceService</b>"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存放用户HTTP session信息的CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"usersessions"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.CacheSourceService</b>"</span><span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"key-type"</span> <span class="na">value=</span><span class="s">"java.lang.String"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"value-type"</span> <span class="na">value=</span><span class="s">"java.lang.Integer"</span><span class="nt">/></span>
|
||
<span class="nt"></service></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<br/>
|
||
|
||
<p> <b>4、微服务部署</b></p>
|
||
<p> 当用户量和发帖量增加到上百万的时候,明显地将所有模块的服务部署到一个进程里是不行的。 因此需要将Service服务都独立部署形成微服务架构。</p>
|
||
<p style="text-align: center;"><img src="images/distributeimg_4.png" alt=""/></p>
|
||
<p> 如上图,将Serivice都独立部署并进行容灾部署,当然如果有需要,Servlet之间、Source都可以各自分离独立部署。不同类型的Service之间都是远程模式调用。</p>
|
||
<p> 接入层中每个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.111"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.121"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.130"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.131"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- HTTP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"HTTP"</span> <span class="na">port=</span><span class="s">"6060"</span> <span class="na">root=</span><span class="s">"root"</span><span class="nt">></span>
|
||
<span class="c"><!-- 前端配置了nginx,需要配置才能获取客户端真实的IP地址 --></span>
|
||
<span class="nt"><request></span>
|
||
<span class="nt"><remoteaddr</span> <span class="na">value=</span><span class="s">"request.headers.X-RemoteAddress"</span><span class="nt">/></span>
|
||
<span class="nt"></request></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.NotifyService"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.ForumService"</span> <span class="na">groups=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 有WebSocketServlet的服务必须配置WebSocketNodeService,且Redkale同时会自动创建一个同名(ws_notify)的 CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"ws_notify"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.WebSocketNodeService</b>"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"><servlets</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="nt">/></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<p> 用户模块UserService服务群中各个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.111"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.121"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.130"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.131"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.NotifyService"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.ForumService"</span> <span class="na">groups=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存在DataSource必须配置DataSourceService --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"demodb"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.DataSourceService</b>"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存放用户HTTP session信息的CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"usersessions"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.CacheSourceService</b>"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"key-type"</span> <span class="na">value=</span><span class="s">"java.lang.String"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"value-type"</span> <span class="na">value=</span><span class="s">"java.lang.Integer"</span><span class="nt">/></span>
|
||
<span class="nt"></service></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<p> 通知模块NotifyService服务群中各个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.111"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.121"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.130"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.131"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.ForumService"</span> <span class="na">groups=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 有WebSocketServlet的服务必须配置WebSocketNodeService,且Redkale同时会自动创建一个同名(ws_notify)的 CacheSource --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"ws_notify"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.WebSocketNodeService</b>"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存在DataSource必须配置DataSourceService --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"demodb"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.DataSourceService</b>"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<p> 帖子模块ForumService服务群中各个进程的配置相同,配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.111"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.120"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.121"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.130"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.131"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"org.redkale.demo.NotifyService"</span> <span class="na">groups=</span><span class="s">"NOTIFY_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 存在DataSource必须配置DataSourceService --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"demodb"</span> <span class="na">value=</span><span class="s">"<b>org.redkale.service.DataSourceService</b>"</span> <span class="na">groups=</span><span class="s">"FORUM_SERVICE"</span><span class="nt">/></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<br/>
|
||
<p> <b>5、API网关式部署</b></p>
|
||
<p> 随着用户量到了上千万时,一个UserService的服务进程是无法提供全部用户服务。 因此可以考虑按用户段进行分布式部署。将192.168.50.110、192.168.50.111上的UserService服务改成网关式的服务。下面是以 <a href="service.html#service_local" target="_blank">Service本地模式介绍中的UserService</a> 为范例进行编写:</p>
|
||
<div class="highlight"><pre><span class="nd">@ResourceType</span><span class="o">({</span><span class="n">UserService</span><span class="o">.</span><span class="kd">class</span><span class="o">})</span>
|
||
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserServiceGateWay</span> <span class="kd">extends</span> <span class="n">UserService</span> <span class="o">{</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_reg"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">regUserService</span><span class="o">;</span> <span class="c1">//只用于注册的服务节点</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_mob"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">mobUserService</span><span class="o">;</span> <span class="c1">//只用于查询手机号码对应的userid的服务节点</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_node01"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">userService01</span><span class="o">;</span> <span class="c1">//userid小于2000000的用户的服务节点</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_node02"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">userService02</span><span class="o">;</span> <span class="c1">//userid小于4000000的用户的服务节点</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_node03"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">userService03</span><span class="o">;</span> <span class="c1">//userid小于6000000的用户的服务节点</span>
|
||
|
||
<span class="nd">@Resource</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"userservice_node04"</span><span class="o">)</span>
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="n">userService04</span><span class="o">;</span> <span class="c1">//userid大于6000000的用户的服务节点</span>
|
||
|
||
<span class="kd">private</span> <span class="n">UserService</span> <span class="nf">getService</span><span class="o">(</span><span class="kt">int</span> <span class="n">userid</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">if</span> <span class="o">(</span><span class="n">userid</span> <span class="o"><=</span> <span class="mi">200_0000</span><span class="o">)</span> <span class="k">return</span> <span class="n">userService01</span><span class="o">;</span>
|
||
<span class="k">if</span> <span class="o">(</span><span class="n">userid</span> <span class="o"><=</span> <span class="mi">400_0000</span><span class="o">)</span> <span class="k">return</span> <span class="n">userService02</span><span class="o">;</span>
|
||
<span class="k">if</span> <span class="o">(</span><span class="n">userid</span> <span class="o"><=</span> <span class="mi">600_0000</span><span class="o">)</span> <span class="k">return</span> <span class="n">userService03</span><span class="o">;</span>
|
||
<span class="k">return</span> <span class="n">userService04</span><span class="o">;</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="n">UserInfo</span> <span class="nf">findUserInfo</span><span class="o">(</span><span class="kt">int</span> <span class="n">userid</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">userid</span><span class="o">).</span><span class="na">findUserInfo</span><span class="o">(</span><span class="n">userid</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="n">RetResult</span><span class="o"><</span><span class="n">UserInfo</span><span class="o">></span> <span class="nf">login</span><span class="o">(</span><span class="n">LoginBean</span> <span class="n">bean</span><span class="o">)</span> <span class="o">{</span> <span class="c1">//手机号码用long存储,0表示无手机号码</span>
|
||
<span class="kt">int</span> <span class="n">userid</span> <span class="o">=</span> <span class="n">mobUserService</span><span class="o">.</span><span class="na">findUserid</span><span class="o">(</span><span class="n">bean</span><span class="o">.</span><span class="na">getMobile</span><span class="o">());</span>
|
||
<span class="k">if</span> <span class="o">(</span><span class="n">userid</span> <span class="o"><</span> <span class="mi">1</span><span class="o">)</span> <span class="k">return</span> <span class="k">new</span> <span class="n">RetResult</span><span class="o"><>(</span><span class="mi">10001</span><span class="o">,</span> <span class="s">"not found mobile "</span> <span class="o">+</span> <span class="n">bean</span><span class="o">.</span><span class="na">getMobile</span><span class="o">());</span>
|
||
<span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">userid</span><span class="o">).</span><span class="na">login</span><span class="o">(</span><span class="n">bean</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">register</span><span class="o">(</span><span class="n">UserInfo</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="n">regUserService</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">user</span><span class="o">);</span> <span class="c1">//会生成userid</span>
|
||
<span class="k">this</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">user</span><span class="o">.</span><span class="na">getUserid</span><span class="o">()).</span><span class="na">putUserInfo</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
|
||
<span class="nd">@Override</span>
|
||
<span class="kd">public</span> <span class="n">UserInfo</span> <span class="nf">updateUsername</span><span class="o">(</span><span class="kt">int</span> <span class="n">userid</span><span class="o">,</span> <span class="n">String</span> <span class="n">username</span><span class="o">)</span> <span class="o">{</span>
|
||
<span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">getService</span><span class="o">(</span><span class="n">userid</span><span class="o">).</span><span class="na">updateUsername</span><span class="o">(</span><span class="n">userid</span><span class="o">,</span> <span class="n">username</span><span class="o">);</span>
|
||
<span class="o">}</span>
|
||
<span class="o">}</span>
|
||
</pre></div>
|
||
<p> 从代码看出,UserServiceGateWay继承了UserService, 确保了UserService对外的服务接口不变,上面代码是用户量在600-800万之间的写法,通过简单的用户ID分段,根据不同用户ID调不同的服务节点。</p>
|
||
<p style="text-align: center;"><img src="images/distributeimg_5.png" alt=""/></p>
|
||
<p> 如上图,网关下的UserService部署分三类: userservice_reg只用于注册用户;userservice_mob提供查询手机号码与用户ID间的关系的服务;userservice_node按用户段提供已有用户的服务。且每个UserService的实例在UserServiceGateWay都是远程模式。每种类型可以部署多个节点(为了结构图简单,上图每个类型只部署一个节点)。UserServiceGateWay(192.168.50.110、192.168.50.111)的配置如下:</p>
|
||
<div class="highlight"><pre><span class="nt"><application</span> <span class="na">port=</span><span class="s">"5050"</span><span class="nt">></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_REG"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_MOB"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.150"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_NODE01"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.201"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_NODE02"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.202"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_NODE03"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.203"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE_NODE04"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.70.204"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">"USER_SERVICE"</span><span class="nt">></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.110"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"192.168.50.111"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="nt"></resources></span>
|
||
|
||
<span class="c"><!-- SNCP 监听 Server --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span><span class="nt">></span>
|
||
<span class="c"><!-- 配置UserService网关 --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">""</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserServiceGateWay"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 配置UserService分段节点 --></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_reg"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_REG"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_mob"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_MOB"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_node01"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_NODE01"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_node02"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_NODE02"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_node03"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_NODE03"</span><span class="nt">/></span>
|
||
<span class="nt"><service</span> <span class="na">name=</span><span class="s">"userservice_node04"</span> <span class="na">value=</span><span class="s">"org.redkale.demo.UserService"</span> <span class="na">groups=</span><span class="s">"USER_SERVICE_NODE03"</span><span class="nt">/></span>
|
||
<span class="nt"></services></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span></pre></div>
|
||
<br/>
|
||
<p> 由以上几种部署方式的范例可以看出,Redkale提供了非常强大的架构,集中式到微服务架构不需要增加修改一行代码即可随意切换,即使网关式部署也只是新增很少的代码就可切换,且不影响其他服务。真正可以做到敏捷开发,复杂的系统都可如小系统般快速地开发出来。<br/>
|
||
为了降低接入层与业务层代码的耦合, 可以将Service分接口与实现两个类,接入层只加载接口包、业务层使用实现包。
|
||
</p>
|
||
<br/>
|
||
|
||
<h3><a id="redkale_confxml" href="#" aria-hidden="true"></a>appplication.xml 配置说明</h3>
|
||
<div class="highlight"><pre><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> 文件说明:</span>
|
||
<span class="c"> ${APP_HOME} 指当前程序的根目录APP_HOME</span>
|
||
<span class="c"> required: 被声明required的属性值不能为空</span>
|
||
<span class="c">--></span>
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> address: 本地的IP地址, 默认值为默认网卡的ip,当不使用默认值需要指定值,如127.0.0.1</span>
|
||
<span class="c"> port: required 程序的管理Server的端口,用于关闭或者与监管系统进行数据交互</span>
|
||
<span class="c"> host: 程序的管理Server的地址; 默认为127.0.0.1。</span>
|
||
<span class="c"> lib: 加上额外的lib路径,多个路径用分号;隔开; 默认为空。 例如: ${APP_HOME}/lib/a.jar;${APP_HOME}/lib2/b.jar;</span>
|
||
<span class="c">--></span>
|
||
<span class="nt"><application</span> <span class="na">port=</span><span class="s">"6560"</span> <span class="na">lib=</span><span class="s">""</span><span class="nt">></span>
|
||
|
||
<span class="c"><!-- 所有服务所需的资源 --></span>
|
||
<span class="nt"><resources></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> transport节点只能有一个,用于配置所有Transport的池参数,没配置该节点将自动创建一个。</span>
|
||
<span class="c"> threads: 线程总数, 默认: <group>节点数*CPU核数*8</span>
|
||
<span class="c"> bufferCapacity: ByteBuffer的初始化大小, 默认: 8K; </span>
|
||
<span class="c"> bufferPoolSize: ByteBuffer池的大小,默认: <group>节点数*CPU核数*8</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><transport</span> <span class="na">capacity=</span><span class="s">"8192"</span> <span class="na">bufferPoolSize=</span><span class="s">"32"</span> <span class="na">threads=</span><span class="s">"32"</span><span class="nt">/></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 一个组包含多个NODE, 同一Service服务可以由多个进程提供,这些进程称为一个GROUP,且同一GROUP内的进程必须在同一机房或局域网内</span>
|
||
<span class="c"> 一个group节点对应一个 Transport 对象。</span>
|
||
<span class="c"> name: 服务组ID,长度不能超过11个字节. 默认为空字符串。 注意: name不能包含$符号。</span>
|
||
<span class="c"> protocol:值只能是UDP TCP, 默认TCP</span>
|
||
<span class="c"> 注意: 一个node只能所属一个group。只要存在protocol=SNCP的Server节点信息, 就必须有group节点信息。</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><group</span> <span class="na">name=</span><span class="s">""</span> <span class="na">protocol=</span><span class="s">"TCP"</span><span class="nt">></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 需要将本地node的addr与port列在此处。</span>
|
||
<span class="c"> 同一个<node>节点值只能存在一个<group>节点内,即同一个addr+port只能属于一个group。</span>
|
||
<span class="c"> addr: required IP地址</span>
|
||
<span class="c"> port: required 端口</span>
|
||
<span class="c"> clients: 连接池数, 默认: CPU核数*4</span>
|
||
<span class="c"> buffers: ByteBuffer对象池的大小, 默认: CPU核数*8</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><node</span> <span class="na">addr=</span><span class="s">"127.0.0.1"</span> <span class="na">port=</span><span class="s">"7070"</span><span class="nt">/></span>
|
||
<span class="nt"></group></span>
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> 全局的参数配置, 可以通过@Resource(name="property.xxxxxx") 进行注入, 被注解的字段类型只能是String、primitive class</span>
|
||
<span class="c"> 如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。</span>
|
||
<span class="c"> 如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。</span>
|
||
<span class="c"> load: 加载文件,多个用;隔开。</span>
|
||
<span class="c"> 默认置入的system.property.的有:</span>
|
||
<span class="c"> System.setProperty("convert.json.tiny", "true");</span>
|
||
<span class="c"> System.setProperty("convert.bson.tiny", "true");</span>
|
||
<span class="c"> System.setProperty("convert.json.pool.size", "128");</span>
|
||
<span class="c"> System.setProperty("convert.bson.pool.size", "128");</span>
|
||
<span class="c"> System.setProperty("convert.json.writer.buffer.defsize", "4096");</span>
|
||
<span class="c"> System.setProperty("convert.bson.writer.buffer.defsize", "4096");</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><properties</span> <span class="na">load=</span><span class="s">"config.properties"</span><span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"system.property.yyyy"</span> <span class="na">value=</span><span class="s">"YYYYYY"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"></properties></span>
|
||
<span class="nt"></resources></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> protocol: required server所启动的协议,有HTTP、SNCP, 目前只支持HTTP、SNCP。SNCP使用TCP实现; </span>
|
||
<span class="c"> host: 服务所占address , 默认: 0.0.0.0</span>
|
||
<span class="c"> port: required 服务所占端口 </span>
|
||
<span class="c"> root: 如果是web类型服务,则包含页面 默认:{APP_HOME}/root</span>
|
||
<span class="c"> lib: server额外的class目录, 默认为空 </span>
|
||
<span class="c"> charset: 文本编码, 默认: UTF-8</span>
|
||
<span class="c"> backlog: 默认10K</span>
|
||
<span class="c"> threads: 线程总数, 默认: CPU核数*16</span>
|
||
<span class="c"> maxbody: request.body最大值, 默认: 64K</span>
|
||
<span class="c"> bufferCapacity: ByteBuffer的初始化大小, 默认: 8K; 如果是HTTP协议则默认: 16K + 8B (兼容HTTP 2.0)</span>
|
||
<span class="c"> bufferPoolSize: ByteBuffer池的大小,默认: CPU核数*512</span>
|
||
<span class="c"> responsePoolSize: Response池的大小,默认: CPU核数*256</span>
|
||
<span class="c"> readTimeoutSecond: 读操作超时秒数, 默认0, 表示永久不超时</span>
|
||
<span class="c"> writeTimeoutSecond: 写操作超时秒数, 默认0, 表示永久不超时 </span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"HTTP"</span> <span class="na">host=</span><span class="s">"127.0.0.1"</span> <span class="na">port=</span><span class="s">"6060"</span> <span class="na">root=</span><span class="s">"root"</span> <span class="na">lib=</span><span class="s">""</span><span class="nt">></span>
|
||
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> 加载所有的Service服务;</span>
|
||
<span class="c"> 在同一个进程中同一个name同一类型的Service将共用同一个实例</span>
|
||
<span class="c"> autoload="true" 默认值. 自动加载以下目录(如果存在的话)下所有的Service类:</span>
|
||
<span class="c"> server.lib; server.lib/*; server.classes; </span>
|
||
<span class="c"> autoload="false" 需要显著的指定Service类</span>
|
||
<span class="c"> includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开</span>
|
||
<span class="c"> excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开 </span>
|
||
<span class="c"> groups: 所属组的节点,多个节点值用;隔开,如果配置文件中存在多个SNCP协议的Server节点,需要显式指定group属性.</span>
|
||
<span class="c"> 当 protocol == SNCP 时 group表示当前Server与哪些节点组关联。</span>
|
||
<span class="c"> 当 protocol != SNCP 时 group只能是空或者一个group的节点值,不能为多个节点值。</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">includes=</span><span class="s">""</span> <span class="na">excludes=</span><span class="s">""</span><span class="nt">></span>
|
||
|
||
<span class="c"><!-- 显著加载指定的Service的接口类 --></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"com.xxx.XXX1Service"</span><span class="nt">/></span>
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> name: 显式指定name,覆盖默认的空字符串值。 注意: name不能包含$符号。</span>
|
||
<span class="c"> groups: 显式指定groups,覆盖<services>节点的groups默认值。</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"com.xxx.XXX2Service"</span> <span class="na">name=</span><span class="s">""</span> <span class="na">groups=</span><span class="s">"xxx;yyy"</span><span class="nt">/></span>
|
||
<span class="c"><!-- 给Service增加配置属性 --></span>
|
||
<span class="nt"><service</span> <span class="na">value=</span><span class="s">"com.xxx.XXX1Service"</span><span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"></service></span>
|
||
<span class="nt"></services></span>
|
||
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 当Server为HTTP协议时, request节点才有效。</span>
|
||
<span class="c"> remoteaddr 节点: 替换请求方节点的IP地址, 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。</span>
|
||
<span class="c"> 且value值只能是以request.headers.开头,表示从request.headers中获取对应的header值。</span>
|
||
<span class="c"> 例如下面例子获取request.getRemoteAddr()值,如果header存在X-RemoteAddress值则返回X-RemoteAddress值,不存在返回getRemoteAddress()。</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><request></span>
|
||
<span class="nt"><remoteaddr</span> <span class="na">value=</span><span class="s">"request.headers.X-RemoteAddress"</span><span class="nt">/></span>
|
||
<span class="nt"></request></span>
|
||
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 当Server为HTTP协议时, response节点才有效。</span>
|
||
<span class="c"> defcookie 节点: 当response里输出的cookie没有指定domain 和path时,使用该节点的默认值。</span>
|
||
<span class="c"> 如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值</span>
|
||
<span class="c"> 例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><response></span>
|
||
<span class="nt"><defcookie</span> <span class="na">domain=</span><span class="s">""</span> <span class="na">path=</span><span class="s">""</span><span class="nt">/></span>
|
||
<span class="nt"><addheader</span> <span class="na">name=</span><span class="s">"Access-Control-Allow-Origin"</span> <span class="na">value=</span><span class="s">"request.headers.Origin"</span> <span class="nt">/></span>
|
||
<span class="nt"><setheader</span> <span class="na">name=</span><span class="s">"Access-Control-Allow-Credentials"</span> <span class="na">value=</span><span class="s">"true"</span><span class="nt">/></span>
|
||
<span class="nt"></response></span>
|
||
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> 加载所有的Servlet服务;</span>
|
||
<span class="c"> path: servlet的ContextPath前缀 默认为空</span>
|
||
<span class="c"> autoload="true" 默认值. 自动加载以下目录(如果存在的话)下所有的Servlet类:</span>
|
||
<span class="c"> ${APP_HOME}/lib; ${APP_HOME}/root/lib/*; ${APP_HOME}/root/classes; </span>
|
||
<span class="c"> autoload="false" 需要显著的指定Service类</span>
|
||
<span class="c"> includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开</span>
|
||
<span class="c"> excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><servlets</span> <span class="na">path=</span><span class="s">"/pipes"</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">includes=</span><span class="s">""</span> <span class="na">excludes=</span><span class="s">""</span><span class="nt">></span>
|
||
<span class="c"><!-- </span>
|
||
<span class="c"> 当Server为HTTP协议时,ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点</span>
|
||
<span class="c"> webroot: web资源的根目录, 默认取server节点中的root值</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><resource-servlet</span> <span class="na">webroot=</span><span class="s">"root"</span><span class="nt">></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 资源缓存的配置, 默认存在一个含默认属性的caches节点</span>
|
||
<span class="c"> limit: 资源缓存最大容量, 默认: 0, 为0表示不缓存, 单位可以是B、K、M、G,不区分大小写</span>
|
||
<span class="c"> lengthmax: 可缓存的文件大小上限, 默认: 1M(超过1M的文件不会被缓存)</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><caches</span> <span class="na">limit=</span><span class="s">"0M"</span> <span class="na">lengthmax=</span><span class="s">"1M"</span> <span class="nt">/></span>
|
||
<span class="c"><!--</span>
|
||
<span class="c"> 支持类似nginx中的rewrite, 目前只支持静态资源对静态资源的跳转。</span>
|
||
<span class="c"> type: 匹配的类型, 目前只支持location(匹配requestURI), 默认: location</span>
|
||
<span class="c"> match: 匹配的正则表达式</span>
|
||
<span class="c"> forward: 需跳转后的资源链接</span>
|
||
<span class="c"> 例如下面例子是将/xxx-yyy.html的页面全部跳转到/xxx.html</span>
|
||
<span class="c"> --></span>
|
||
<span class="nt"><rewrite</span> <span class="na">type=</span><span class="s">"location"</span> <span class="na">match=</span><span class="s">"^/([^-]+)-[^-\.]+\.html(.*)"</span> <span class="na">forward=</span><span class="s">"/$1.html"</span><span class="nt">/></span>
|
||
<span class="nt"></resource-servlet></span>
|
||
<span class="c"><!-- 显著加载指定的Servlet --></span>
|
||
<span class="nt"><servlet</span> <span class="na">value=</span><span class="s">"com.xxx.XXX1Servlet"</span> <span class="nt">/></span>
|
||
<span class="nt"><servlet</span> <span class="na">value=</span><span class="s">"com.xxx.XXX2Servlet"</span> <span class="nt">/></span>
|
||
<span class="nt"><servlet</span> <span class="na">value=</span><span class="s">"com.xxx.XXX3Servlet"</span> <span class="nt">></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"xxxxxx"</span> <span class="na">value=</span><span class="s">"XXXXXXXX"</span><span class="nt">/></span>
|
||
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"yyyyyy"</span> <span class="na">value=</span><span class="s">"YYYYYYYY"</span><span class="nt">/></span>
|
||
<span class="nt"></servlet></span>
|
||
<span class="nt"></servlets></span>
|
||
<span class="nt"></server></span>
|
||
|
||
<span class="nt"><server</span> <span class="na">protocol=</span><span class="s">"SNCP"</span> <span class="na">host=</span><span class="s">"127.0.0.1"</span> <span class="na">port=</span><span class="s">"7070"</span> <span class="na">root=</span><span class="s">"root"</span> <span class="na">lib=</span><span class="s">""</span><span class="nt">></span>
|
||
<span class="c"><!-- 参数完全同上 --></span>
|
||
<span class="nt"><services</span> <span class="na">autoload=</span><span class="s">"true"</span> <span class="na">includes=</span><span class="s">""</span> <span class="na">excludes=</span><span class="s">""</span> <span class="nt">/></span>
|
||
<span class="nt"></server></span>
|
||
<span class="nt"></application></span>
|
||
</pre></div>
|
||
|
||
<footer class="site-footer">
|
||
<span class="site-footer-owner"> 欢迎加入Redkale QQ群: 527523235</span>
|
||
</footer>
|
||
|
||
</section>
|
||
|
||
<script>
|
||
var _hmt = _hmt || [];
|
||
(function () {
|
||
var hm = document.createElement("script");
|
||
hm.src = "//hm.baidu.com/hm.js?b4e05d7de8b5f3401dd93e3c6b35ffa5";
|
||
var s = document.getElementsByTagName("script")[0];
|
||
s.parentNode.insertBefore(hm, s);
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|