diff --git a/redkale.html b/redkale.html index 6e5958c83..89d97ecea 100644 --- a/redkale.html +++ b/redkale.html @@ -516,281 +516,340 @@

application.xml 配置说明

<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-    文件说明:
-        ${APP_HOME} 指当前程序的根目录APP_HOME
-        没注明唯一的节点可多个存在
-        required: 被声明required的属性值不能为空
-        
-                                            group
-                                         /  /  \  \  
-                                      /    /    \   \   
-                                   /     /       \    \                      
-                               node1   node2   node3  node4
-                             /       \                             
-                          /             \
-                       /                   \
-                    /                         \
-             serviceid1                       serviceid2
-            /       \                        /           \
-  serviceid1_name1  serviceid1_name2   serviceid2_name1  serviceid2_name2    
--->
-<!--     
-    address:  本地局域网的IP地址, 默认值为默认网卡的ip,当不使用默认值需要指定值,如192.168.1.22
-    port: required  程序的管理Server的端口,用于关闭或者与监管系统进行数据交互
-    lib:  加上额外的lib路径,多个路径用分号;隔开; 默认为空。  例如: ${APP_HOME}/lib/a.jar;${APP_HOME}/lib2/b.jar;
--->
-<application port="6560" lib="">  
-    
-    <!-- 
-        【节点全局唯一】
-        所有服务所需的资源 
-    -->
-    <resources>  
-        
-        <!--
-            【节点全局唯一】
-            transport节点只能有一个,用于配置所有Transport的池参数,没配置该节点将自动创建一个。
-            threads: 线程总数, 默认: <group>节点数*CPU核数*2
-            bufferCapacity: ByteBuffer的初始化大小, 默认: 32K; 
-            bufferPoolSize: ByteBuffer池的大小,默认: 线程总数*4
-            readTimeoutSecond: TCP读取超时秒数, 默认为6秒, 为0表示无超时限制
-            writeTimeoutSecond: TCP写入超时秒数, 默认为6秒, 为0表示无超时限制
-            strategy: 远程请求的负载均衡策略, 必须是org.redkale.net.TransportStrategy的实现类
-        -->
-        <transport bufferCapacity="32K" bufferPoolSize="32" threads="32" readTimeoutSecond="6" writeTimeoutSecond="6"/>
-        
-        <!--
-            一个组包含多个node, 同一Service服务可以由多个进程提供,这些进程称为一个GROUP,且同一GROUP内的进程必须在同一机房或局域网内
-            一个group节点对应一个 Transport 对象。
-            name: 服务组ID,长度不能超过11个字节. 默认为空字符串。 注意: name不能包含$符号。
-            protocol:值范围:UDP TCP, 默认TCP
-            subprotocol: 子协议,预留字段。默认值为空
-            注意: 一个node只能所属一个group。只要存在protocol=SNCP的Server节点信息, 就必须有group节点信息。
-        -->
-        <group name="" protocol="TCP">
-            <!--
-                需要将本地node的addr与port列在此处。
-                同一个<node>节点值只能存在一个<group>节点内,即同一个addr+port只能属于一个group。
-                addr: required IP地址
-                port: required 端口
-            -->
-            <node addr="127.0.0.1" port="7070"/>
-        </group>
-        
-        <!--
-            全局的数据源设置, 可以是CacheSource、DataSource, JDBC的DataSource通常通过persistence.xml配置,此处多用于CacheSource的配置
-            name:  资源名,用于依赖注入。
-            value:类名,必须是CacheSource或DataSource的子类,且必须实现Service接口。如果是DataSource.class,系统自动映射成DataJdbcSource.class
-            groups: 指定groups。
-            xxx: 其他属性与子节点通过Service.init方法传入的AnyValue获取。
-        -->
-        <source name="redis" value="org.redkalex.cache.RedisCacheSource" xxx="16">
-            <node addr="127.0.0.1" port="7070"/>
-        </source>
-        
-        <!--
-           Application启动的监听事件,可配置多个节点
-           value: 类名,必须是ApplicationListener的子类
-        -->
-        <listener value="org.redkalex.xxx.XXXApplicationListener"/>
-        
-        <!-- 
-            【节点全局唯一】
-            全局的参数配置, 可以通过@Resource(name="property.xxxxxx") 进行注入<property>的信息, 被注解的字段类型只能是String、primitive class
-            如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。
-            如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。
-            load:  加载文件,多个用;隔开。
-            默认置入的system.property.的有:
-               System.setProperty("net.transport.pinginterval", "30");
-               System.setProperty("convert.json.tiny", "true");
-               System.setProperty("convert.bson.tiny", "true");
-               System.setProperty("convert.json.pool.size", "128");
-               System.setProperty("convert.bson.pool.size", "128");
-               System.setProperty("convert.json.writer.buffer.defsize", "4096");
-               System.setProperty("convert.bson.writer.buffer.defsize", "4096");
-               
-            <properties>节点下也可包含非<property>节点.
-            非<property>其节点可以通过@Resource(name="properties.xxxxxx")进行注入, 被注解的字段类型只能是AnyValue、AnyValue[]
-        -->
-        <properties load="config.properties">
-            <property name="system.property.yyyy" value="YYYYYY"/>
+<!-- 
+    文件说明:
+        ${APP_HOME} 指当前程序的根目录APP_HOME
+        没注明唯一的节点可多个存在
+        required: 被声明required的属性值不能为空
+        
+                                            group
+                                         /  /  \  \  
+                                      /    /    \   \   
+                                   /     /       \    \                      
+                               node1   node2   node3  node4
+                             /       \                             
+                          /             \
+                       /                   \
+                    /                         \
+             serviceid1                       serviceid2
+            /       \                        /           \
+  serviceid1_name1  serviceid1_name2   serviceid2_name1  serviceid2_name2    
+-->
+<!--     
+    nodeid: int     进程的节点ID,用于分布式环境,一个系统中节点ID必须全局唯一,使用cluster时框架会进行唯一性校验
+    name:           进程的名称,用于监控识别,命名规则: 字母、数字、下划线、短横、点
+    address:        本地局域网的IP地址, 默认值为默认网卡的ip,当不使用默认值需要指定值,如192.168.1.22
+    port: required  程序的管理Server的端口,用于关闭或者与监管系统进行数据交互
+    lib:            加上额外的lib路径,多个路径用分号;隔开; 默认为空。  例如: ${APP_HOME}/lib/a.jar;${APP_HOME}/lib2/b.jar;
+-->
+<application nodeid="1000" port="6560" lib="">  
+
+    <!--
+       【节点全局唯一】 @since 2.3.0
+        全局Serivce执行的线程池, Application.workExecutor, 没配置该节点将自动创建一个。
+        threads: 线程数,为0表示不启用workExecutor,只用IO线程。默认: CPU核数, 核数=1的情况下默认值为2
+    -->
+    <executor threads="4"/>
+
+    <!--
+       【节点全局唯一】
+        第三方服务发现管理接口
+        type:          类名,必须是org.redkale.cluster.ClusterAgent的子类
+        waits:          注销服务后是否需要等待检查周期时间后再进行Service销毁,默认值为:false
+                        当一个Service进行服务注销后,不能立刻销毁Service,因为健康检测是有间隔时间差的,
+                        需要等待一个健康检测周期时间,让其他进程都更新完服务列表。
+                        如果使用MQ,可以设置为false,如果对服务健壮性要求高,建议设置为true
+        protocols:      服务发现可以处理的协议, 默认值为: SNCP, 多个协议用分号;隔开
+        ports:          服务发现可以处理的端口, 多个端口用分号;隔开
+        ttls:           心跳频率,多少秒一次
+        xxxx:           自定义的字段属性,例如:CacheClusterAgent有source字段; ConsulClusterAgent有apiurl字段;
+    -->
+    <cluster type="org.redkalex.cluster.consul.ConsulClusterAgent" waits="false" protocols="SNCP" ports="7070;7071" xxx="xxx" />
+
+    <!--
+        MQ管理接口配置
+        不同MQ节点所配置的MQ集群不能重复。
+        MQ跟着协议走,所以mq的属性值需要被赋值在rest节点上, 由于SncpServlet是自动生成的,故SNCP协议下,mq属性值被赋值在service/services节点上
+        name:    服务的名称,用于监控识别,多个mq节点时只能有一个name为空的节点,mq.name不能重复,命名规则: 字母、数字、下划线
+        type:   实现类名,必须是org.redkale.mq.MessageAgent的子类
+        threads:线程数,为0表示使用workExecutor。默认: CPU核数, 核数=1的情况下默认值为2,JDK 21以上版本默认使用虚拟线程池
+        rpcfirst:cluster和mq同名组件时,HttpRpcClient优先使用MQ,默认不优先走MQ。
+        coder:   MessageRecord的解析器类,必须是org.redkale.mq.MessageCoder<MessageRecord>的实现类, 
+             可对数据包进行加密解密,默认值:org.redkale.mq.MessageRecordCoder
+        MQ节点下的子节点配置没有固定格式, 根据MessageAgent实现方的定义来配置
+    -->
+    <mq name="" type="org.redkalex.mq.kafka.KafkaMessageAgent" rpcfirst="false" threads="4">
+        <servers value="127.0.0.1:9101"/>
+        <!--        
+           加载所有的MessageConsumer实例;
+           autoload="true"  默认值. 自动加载classpath下所有的MessageConsumer类  
+           autoload="false" 需要显著的指定MessageConsumer类
+           includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+           excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开           
+        -->
+        <consumer autoload="true" includes="" excludes=""/>
+        <!--
+            MQ实现方的配置项
+          type:  配置项类型,值只能是consumer或producer
+        -->
+        <config type="consumer">
             <property name="xxxxxx" value="XXXXXXXX"/>
+        </config>
+        <config type="producer">
             <property name="xxxxxx" value="XXXXXXXX"/>
-            <property name="xxxxxx" value="XXXXXXXX"/>
-        </properties>
-                
-    </resources> 
-    <!--
-        protocol: required  server所启动的协议,Redkale内置的有HTTP、SNCP、WATCH。协议均使用TCP实现; WATCH服务只能存在一个。
-        name: 服务的名称,用于监控识别,一个配置文件中的server.name不能重复,命名规则: 字母、数字、下划线
-        host:  服务所占address , 默认: 0.0.0.0
-        port:  required 服务所占端口 
-        root:  如果是web类型服务,则包含页面  默认:{APP_HOME}/root
-        lib: server额外的class目录, 默认为${APP_HOME}/libs/*; 
-        excludelibs: 排除lib.path与excludes中的正则表达式匹配的路径, 多个正则表达式用分号;隔开
-        charset: 文本编码, 默认: UTF-8
-        backlog:  默认10K
-        threads: 线程总数, 默认: CPU核数*8
-        maxconns:最大连接数, 小于1表示无限制, 默认: 0
-        maxbody: request.body最大值, 默认: 64K
-        bufferCapacity: ByteBuffer的初始化大小, 默认: 32K;  (HTTP 2.0、WebSocket,必须要16k以上)
-        bufferPoolSize: ByteBuffer池的大小,默认: 线程总数*4
-        responsePoolSize: Response池的大小,默认: 线程总数*2
-        readTimeoutSecond: 读操作超时秒数, 默认0, 表示永久不超时
-        writeTimeoutSecond:  写操作超时秒数, 默认0, 表示永久不超时
-        interceptor: 启动/关闭NodeServer时被调用的拦截器实现类,必须是org.redkale.boot.NodeInterceptor的子类,默认为null
-    -->
+        </config>
+    </mq>
+        
+    <!--
+        一个组包含多个node, 同一Service服务可以由多个进程提供,这些进程称为一个GROUP,且同一GROUP内的进程必须在同一机房或局域网内
+        name:       服务组ID,长度不能超过11个字节. 默认为空字符串。 注意: name不能包含$符号。
+        protocol:  值范围:UDP TCP, 默认TCP
+        注意: 一个node只能所属一个group。只要存在protocol=SNCP的Server节点信息, 就必须有group节点信息。
+    -->
+    <group name="" protocol="TCP">
+        <!--
+            需要将本地node的addr与port列在此处。
+            同一个<node>节点值只能存在一个<group>节点内,即同一个addr+port只能属于一个group。
+            addr: required IP地址
+            port: required 端口
+        -->
+        <node addr="127.0.0.1" port="7070"/>
+    </group>
+
+    <!--
+       Application启动的监听事件,可配置多个节点
+       value: 类名,必须是ApplicationListener的子类
+    -->
+    <listener value="org.redkalex.xxx.XXXApplicationListener"/>
+        
+    <!-- 
+        【节点全局唯一】
+        全局的参数配置, 可以通过@Resource(name="property.xxxxxx") 进行注入<property>的信息, 被注解的字段类型只能是String、primitive class
+        如果name是system.property.开头的值将会在进程启动时进行System.setProperty("yyyy", "YYYYYY")操作。
+        如果name是mimetype.property.开头的值将会在进程启动时进行MimeType.add("yyyy", "YYYYYY")操作。
+        先加载子节点property,再加载load文件, 最后加载agent的实现子类。
+        load:  加载文件,多个用;隔开。
+        其他属性: 供org.redkale.boot.PropertiesAgentProvider使用判断
+        默认置入的system.property.的有:
+           System.setProperty("redkale.convert.pool.size", "128");
+           System.setProperty("redkale.convert.writer.buffer.defsize", "4096");
+           
+        <properties>节点下也可包含非<property>节点.
+        非<property>其节点可以通过@Resource(name="properties.xxxxxx")进行注入, 被注解的字段类型只能是AnyValue、AnyValue[]
+    -->
+    <properties load="config.properties">
+        <property name="system.property.yyyy" value="YYYYYY"/>
+        <property name="xxxxxx" value="XXXXXXXX"/>
+        <property name="xxxxxx" value="XXXXXXXX"/>
+        <property name="xxxxxx" value="XXXXXXXX"/>
+    </properties>
+        
+    <!--
+        protocol: required   server所启动的协议,Redkale内置的有HTTP、SNCP、WATCH。协议均使用TCP实现; WATCH服务只能存在一个。
+        name:                服务的名称,用于监控识别,一个配置文件中的server.name不能重复,命名规则: 字母、数字、下划线
+        host:                服务所占address , 默认: 0.0.0.0
+        port:                required 服务所占端口 
+        root:                如果是web类型服务,则包含页面  默认:{APP_HOME}/root
+        lib:                 server额外的class目录, 默认为${APP_HOME}/libs/*; 
+        excludelibs:         排除lib.path与excludes中的正则表达式匹配的路径, 多个正则表达式用分号;隔开
+        charset:             文本编码, 默认: UTF-8
+        backlog:             默认10K
+        maxconns:           最大连接数, 小于1表示无限制, 默认: 0
+        maxbody:             request.body最大值, 默认: 256K
+        bufferCapacity:      ByteBuffer的初始化大小, TCP默认: 32K;  (HTTP 2.0、WebSocket,必须要16k以上); UDP默认: 8K
+        bufferPoolSize:     ByteBuffer池的大小,默认: 线程数*4
+        responsePoolSize:   Response池的大小,默认: 1024
+        aliveTimeoutSeconds: KeepAlive读操作超时秒数, 默认30, 0表示永久不超时; -1表示禁止KeepAlive
+        readTimeoutSeconds:  读操作超时秒数, 默认0, 0表示永久不超时
+        writeTimeoutSeconds: 写操作超时秒数, 默认0, 0表示永久不超时
+        interceptor:         启动/关闭NodeServer时被调用的拦截器实现类,必须是org.redkale.boot.NodeInterceptor的子类,默认为null
+    -->
     <server protocol="HTTP" host="127.0.0.1" port="6060" root="root" lib=""> 
         
-        <!-- 
-           加载所有的Service服务;
-           在同一个进程中同一个name同一类型的Service将共用同一个实例
-           autoload="true"  默认值. 自动加载classpath下所有的Service类  
-           autoload="false" 需要显著的指定Service类
-           includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-           excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开           
-           groups:   所属组的节点,多个节点值用;隔开,如果配置文件中存在多个SNCP协议的Server节点,需要显式指定group属性.
-                    当 protocol == SNCP 时 group表示当前Server与哪些节点组关联。
-                    当 protocol != SNCP 时 group只能是空或者一个group的节点值,不能为多个节点值。
-        -->
+        <!-- 
+           【节点在<server>中唯一】
+           builder:             创建SSLContext的实现类, 可自定义,必须是org.redkale.net.SSLBuilder的子类
+           sslProvider:         java.security.Provider自定义的实现类,如第三方: org.conscrypt.OpenSSLProvider、org.bouncycastle.jce.provider.BouncyCastleProvider
+           jsseProvider:        java.security.Provider自定义的实现类,如第三方: org.conscrypt.JSSEProvider、   org.bouncycastle.jce.provider.BouncyCastleJsseProvider
+           protocol:            TLS版本,默认值: TLS
+           protocols:           设置setEnabledProtocols, 多个用,隔开 如: TLSv1.2,TLSv1.3
+           clientAuth:          WANT/NEED/NONE, 默认值: NONE
+           ciphers:             设置setEnabledCipherSuites, 多个用,隔开 如: TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256
+           keystorePass:        KEY密码
+           keystoreFile:        KEY文件 .jks
+           keystoreType:        KEY类型, 默认值为JKS
+           keystoreAlgorithm:   KEY文件的algorithm, 默认值为SunX509
+           truststorePass:      TRUST密码
+           truststoreFile:      TRUST文件
+           truststoreType:      TRUST类型, 默认值为JKS
+           truststoreAlgorithm: TRUST文件的algorithm, 默认值为SunX509
+        -->
+        <ssl builder=""/>
+        
+        <!-- 
+           加载所有的Service服务;
+           在同一个进程中同一个name同一类型的Service将共用同一个实例
+           autoload="true"  默认值. 自动加载classpath下所有的Service类  
+           autoload="false" 需要显著的指定Service类
+           mq:        所属的MQ管理器,当 protocol == SNCP 时该值才有效, 存在该属性表示Service的SNCP协议采用消息总线代理模式
+           includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+           excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开           
+           group:     所属组的节点, 不能指定多个group, 如果配置文件中存在多个SNCP协议的Server节点,需要显式指定group属性.
+                         当 protocol == SNCP 时 group表示当前Server与哪些节点组关联。
+                         当 protocol != SNCP 时 group只能是空或者一个group的节点值。
+                         特殊值"$remote", 视为通过第三方服务注册发现管理工具来获取远程模式的ip端口信息
+        -->
         <services autoload="true" includes="" excludes="">
 
-            <!-- 显著加载指定的Service的接口类 -->
+            <!-- 显著加载指定的Service的接口类 -->
             <service value="com.xxx.XXX1Service"/>
-            <!-- 
-               name:   显式指定name,覆盖默认的空字符串值。 注意: name不能包含$符号。
-               groups: 显式指定groups,覆盖<services>节点的groups默认值。
-               ignore: 是否禁用, 默认为false。
-            -->
-            <service value="com.xxx.XXX2Service" name="" groups="xxx;yyy"/>
-            <!--   给Service增加配置属性 -->
+            <!-- 
+               name:   显式指定name,覆盖默认的空字符串值。 注意: name不能包含$符号。
+               mq:     所属的MQ管理器,当 protocol == SNCP 时该值才有效, 存在该属性表示Service的SNCP协议采用消息总线代理模式
+               group:  显式指定group,覆盖<services>节点的group默认值。
+               ignore: 是否禁用, 默认为false。
+            -->
+            <service value="com.xxx.XXX2Service" name="" group="xxx"/>
+            <!--   给Service增加配置属性 -->
             <service value="com.xxx.XXX1Service"> 
-                <!-- property值在public void init(AnyValue conf)方法中可以通过AnyValue properties=conf.getAnyValue("properties")获取 -->
+                <!-- property值在public void init(AnyValue conf)方法中可以通过AnyValue properties=conf.getAnyValue("properties")获取 -->
                 <property name="xxxxxx" value="XXXXXXXX"/>  
                 <property name="xxxxxx" value="XXXXXXXX"/>
             </service>
         </services>
         
-        <!-- 
-           加载所有的Filter服务;
-           autoload="true"  默认值.  
-           autoload="false" 需要显著的指定Filter类
-           includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-           excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开    
-        -->
+        <!-- 
+           加载所有的Filter服务;
+           autoload="true"  默认值.  
+           autoload="false" 需要显著的指定Filter类
+           includes:       当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+           excludes:       当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开    
+        -->
         <filters autoload="true" includes="" excludes="">
             
-            <!-- 
-               显著加载指定的Filter类
-               value=: Filter类名。必须与Server的协议层相同,HTTP必须是HttpFilter
-               ignore: 是否禁用, 默认为false。
-            -->
-            <!-- 显著加载指定的Filter类 -->
+            <!-- 
+               显著加载指定的Filter类
+               value=: Filter类名。必须与Server的协议层相同,HTTP必须是HttpFilter
+               ignore: 是否禁用, 默认为false。
+            -->
+            <!-- 显著加载指定的Filter类 -->
             <filter value="com.xxx.XXX1Filter"/>
             
-            <!--   给Filter增加配置属性 -->
+            <!--   给Filter增加配置属性 -->
             <filter value="com.xxx.XXX12Filter"> 
-                <!-- property值在public void init(AnyValue conf)方法中可以通过AnyValue properties=conf.getAnyValue("properties")获取 -->
+                <!-- property值在public void init(AnyValue conf)方法中可以通过AnyValue properties=conf.getAnyValue("properties")获取 -->
                 <property name="xxxxxx" value="XXXXXXXX"/>  
                 <property name="xxxxxx" value="XXXXXXXX"/>
             </filter>
         </filters>
         
-        <!-- 
-           REST的核心配置项
-           当Server为HTTP协议时, rest节点才有效。存在[rest]节点则Server启动时会加载REST服务, 节点可以多个,(WATCH协议不需要设置,系统会自动生成)
-           path:     servlet的ContextPath前缀 默认为空
-           base:     REST服务的BaseServlet,必须是 org.redkale.net.http.HttpServlet 的子类,且子类必须标记@HttpUserType。
-           autoload:默认值"true"  默认值. 加载当前server所能使用的Servce对象;    
-           includes:当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-           excludes:当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-        -->
+        <!-- 
+           REST的核心配置项
+           当Server为HTTP协议时, rest节点才有效。存在[rest]节点则Server启动时会加载REST服务, 节点可以多个,(WATCH协议不需要设置,系统会自动生成)
+           path:     servlet的ContextPath前缀 默认为空 【注: 开启MQ时,该字段失效】
+           base:     REST服务的BaseServlet,必须是 org.redkale.net.http.HttpServlet 的子类,且子类必须标记@HttpUserType。
+           mq:        所属的MQ管理器, 存在该属性表示RestService的请求来自于消息总线 【注: 开启MQ时,path字段失效】
+           autoload:默认值"true"  默认值. 加载当前server所能使用的Servce对象;    
+           includes:当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+           excludes:当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+        -->
         <rest path="/pipes" base="org.redkale.net.http.HttpServlet" autoload="true" includes="" excludes="">
-            <!-- 
-               value:  Service类名,列出的表示必须被加载的Service对象
-               ignore: 是否忽略,设置为true则不会加载该Service对象,默认值为false
-            -->
+            <!-- 
+               value:  Service类名,列出的表示必须被加载的Service对象
+               ignore: 是否忽略,设置为true则不会加载该Service对象,默认值为false
+            -->
             <service value="com.xxx.XXXXService"/>
-            <!-- 
-               value:  WebSocket类名,列出的表示必须被加载且标记为@RestWebSocket的WebSocket对象
-               ignore: 是否忽略,设置为true则不会加载该RestWebSocket对象,默认值为false
-            -->
+            <!-- 
+               value:  WebSocket类名,列出的表示必须被加载且标记为@RestWebSocket的WebSocket对象
+               ignore: 是否忽略,设置为true则不会加载该RestWebSocket对象,默认值为false
+            -->
             <websocket value="com.xxx.XXXXRestWebSocket"/>
         </rest>
         
-        <!--
-           【节点在<server>中唯一】
-           当Server为HTTP协议时, request节点才有效。
-           remoteaddr 节点: 替换请求方节点的IP地址, 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。
-           且value值只能是以request.headers.开头,表示从request.headers中获取对应的header值。
-           例如下面例子获取request.getRemoteAddr()值,如果header存在X-RemoteAddress值则返回X-RemoteAddress值,不存在返回getRemoteAddress()。
-        -->
+        <!--
+           【节点在<server>中唯一】
+           当Server为HTTP协议时, request节点才有效。
+           remoteaddr 节点: 替换请求方节点的IP地址, 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。
+           且value值只能是以request.headers.开头,表示从request.headers中获取对应的header值。
+           locale value值必须是request.headers.或request.parameters.开头。
+           例如下面例子获取request.getRemoteAddr()值,如果header存在X-RemoteAddress值则返回X-RemoteAddress值,不存在返回getRemoteAddress()。
+        -->
         <request>
             <remoteaddr value="request.headers.X-RemoteAddress"/>
+            <locale value="request.headers.locale" /> 
+            <rpc authenticator="org.redkale.net.http.HttpRpcAuthenticator的实现类"/>
         </request>
         
-        <!--
-           【节点在<server>中唯一】
-           当Server为HTTP协议时, response节点才有效。
-           defcookie 节点: 当response里输出的cookie没有指定domain 和path时,使用该节点的默认值。
-           如果addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值
-           如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值
-           例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。
-           options 节点: 设置了该节点却auto=true,当request的method=OPTIONS自动设置addheader、setheader并返回200状态码
-        -->
+        <!--
+           【节点在<server>中唯一】
+           当Server为HTTP协议时, response节点才有效。
+           contenttype: plain值为调用finish时的ContentType; 默认值: text/plain; charset=utf-8
+                        json值为调用finishJson时的ContentType; 默认值: application/json; charset=utf-8
+           defcookie 节点: 当response里输出的cookie没有指定domain 和path时,使用该节点的默认值。
+           addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值
+           addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值
+           例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。
+           options 节点: 设置了该节点且auto=true,当request的method=OPTIONS自动设置addheader、setheader并返回200状态码
+           date 节点: 设置了该节点且period有值(单位:毫秒);返回response会包含Date头信息,默认为period=0
+                      period=0表示实时获取当前时间;
+                      period<0表示不设置date;
+                      period>0表示定时获取时间; 设置1000表示每秒刷新Date时间
+        -->
         <response>
+            <content-type plain="text/plain; charset=utf-8" json="application/json; charset=utf-8"/>            
             <defcookie domain="" path=""/>  
-            <addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" /> 
-            <setheader name="Access-Control-Allow-Headers" value="request.headers.Access-Control-Request-Headers"/>
+            <addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" />  <!-- 可多节点 -->
+            <setheader name="Access-Control-Allow-Headers" value="request.headers.Access-Control-Request-Headers"/>  <!-- 可多节点 -->
             <setheader name="Access-Control-Allow-Credentials" value="true"/>
             <options auto="true" />
+            <date period="0" />
         </response>
-        <!-- 
-           【节点在<server>中唯一】
-           当Server为HTTP协议时,render才有效. 指定输出引擎的实现类
-           value: 输出引擎的实现类, 必须是org.redkale.net.http.HttpRender的子类
-        -->
-        <render value="org.redkalex.htel.HttpTemplateRender"/>
-        <!-- 
-           【节点在<server>中唯一】
-           当Server为HTTP协议时,ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
-           webroot: web资源的根目录, 默认取server节点中的root值
-           servlet: 静态资源HttpServlet的实现,默认使用HttpResourceServlet
-           index : 启始页,默认值:index.html
-        -->
+        <!-- 
+           【节点在<server>中唯一】
+           当Server为HTTP协议时,render才有效. 指定输出引擎的实现类
+           value: 输出引擎的实现类, 必须是org.redkale.net.http.HttpRender的子类
+           suffixs: 引擎文件名后缀,多个用;隔开,默认值为: .htel
+        -->
+        <render value="org.redkalex.htel.HttpTemplateRender" suffixs=".htel"/>
+        <!-- 
+           【节点在<server>中唯一】
+           当Server为HTTP协议时,ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
+           webroot: web资源的根目录, 默认取server节点中的root值
+           servlet: 静态资源HttpServlet的实现,默认使用HttpResourceServlet
+           index :  启始页,默认值:index.html
+        -->
         <resource-servlet webroot="root" index="index.html">
-            <!--
-                【节点在<resource-servlet>中唯一】
-                资源缓存的配置, 默认存在一个含默认属性的caches节点
-                limit:  资源缓存最大容量, 默认: 0, 为0表示不缓存, 单位可以是B、K、M、G,不区分大小写
-                lengthmax: 可缓存的文件大小上限, 默认: 1M(超过1M的文件不会被缓存)
-                watch: 是否监控缓存文件的变化, 默认为false,不监控
-            -->
+            <!--
+                【节点在<resource-servlet>中唯一】
+                资源缓存的配置, 默认存在一个含默认属性的caches节点
+                limit:     资源缓存最大容量, 默认: 0, 为0表示不缓存, 单位可以是B、K、M、G,不区分大小写
+                lengthmax: 可缓存的文件大小上限, 默认: 1M(超过1M的文件不会被缓存)
+                watch:     是否监控缓存文件的变化, 默认为false,不监控
+            -->
             <cache  limit="0M" lengthmax="1M" watch="false"/>
-            <!--
-               支持类似nginx中的rewrite, 目前只支持静态资源对静态资源的跳转。
-               type: 匹配的类型, 目前只支持location(匹配requestURI), 默认: location
-               match: 匹配的正则表达式
-               forward: 需跳转后的资源链接
-               例如下面例子是将/xxx-yyy.html的页面全部跳转到/xxx.html
-            -->
+            <!--
+               支持类似nginx中的rewrite, 目前只支持静态资源对静态资源的跳转。
+               type:    匹配的类型, 目前只支持location(匹配requestURI), 默认: location
+               match:   匹配的正则表达式
+               forward: 需跳转后的资源链接
+               例如下面例子是将/xxx-yyy.html的页面全部跳转到/xxx.html
+            -->
             <rewrite type="location" match="^/([^-]+)-[^-\.]+\.html(.*)" forward="/$1.html"/>
         </resource-servlet>
-        <!-- 
-           加载所有的Servlet服务;
-           path:  servlet的ContextPath前缀 默认为空
-           autoload="true"  默认值. 自动加载classpath下所有的Servlet类 
-           autoload="false" 需要显著的指定Service类
-           includes: 当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-           excludes: 当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-        -->
+        <!-- 
+           加载所有的Servlet服务;
+           path:            servlet的ContextPath前缀 默认为空
+           autoload="true"  默认值. 自动加载classpath下所有的Servlet类 
+           autoload="false" 需要显著的指定Service类
+           includes:       当autoload="true", 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+           excludes:       当autoload="true", 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
+        -->
         <servlets path="/pipes" autoload="true" includes="" excludes="">
-            <!-- 
-               显著加载指定的Servlet类
-               value=: Servlet类名。必须与Server的协议层相同,HTTP必须是HttpServlet
-               ignore: 是否禁用, 默认为false。
-            -->
+            <!-- 
+               显著加载指定的Servlet类
+               value=: Servlet类名。必须与Server的协议层相同,HTTP必须是HttpServlet
+               ignore: 是否禁用, 默认为false。
+            -->
             <servlet value="com.xxx.XXX1Servlet" />
             <servlet value="com.xxx.XXX2Servlet" />
             <servlet value="com.xxx.XXX3Servlet" >
@@ -801,9 +860,10 @@
     </server>
     
     <server protocol="SNCP" host="127.0.0.1" port="7070" root="root" lib=""> 
-        <!-- 参数完全同上 -->
+        <!-- 参数完全同上 -->
         <services autoload="true" includes="" excludes="" />
     </server>
+    
 </application>