7.3 应用配置
一个Limax运营环境由一个auany服务器支撑,一个运营环境下可以运行多个应用下的服务,每个应用可以运行多个并列服务,一个服务可以由多个Provider构成。对于一个特定的应用,允许Provider发布公共信息提供给客户端使用。
-
Provider信息发布
Provider的框架周期性向应用Provider请求JSON对象,该对象最终通过auany的http服务发布出去。
-
实现
public interface JSONPublisher { JSONSerializable getJSON(); long getDelay(); }
Provider实现ProviderListener的同时,与之并列实现JSONPublisher接口,其中:
getJSON:返回一个JSON对象。
getDelay:系统下一次获取JSON对象的延迟,单位毫秒。
-
配置
Provider无需额外配置,auany的应用配置中存在一个jsonPublishDelayMin属性(之后介绍),该属性约束了delay的最小值,也就是说, max(jsonPublishDelayMin, JSONPublisher.getDelay())决定了实际延迟,这个配置属性可以防止JSONPublisher的错误实现导致Provider攻击auany。
-
-
Endpoint应用信息获取
endpoint向auany提供的http服务器请求应用配置信息,解析为对应语言的描述。实现上即是访问 http://auanyserver/app?{servicetype}=appid[&additionalQuery], 获取一个JSON对象进行解析,其中servicetype : { native, ws, wss },对于非WebSocket应用,servicetype=native。additionalQuery为http代理服务器约定的查询参数,用以过滤auany返回的结果集。
-
实现
List<ServiceInfo> Endpoint.loadServiceInfos(String httpHost, int httpPort, int appid, long timeout, int maxsize, File cacheDir, boolean staleEnable); List<ServiceInfo> Endpoint.loadServiceInfos(String httpHost, int httpPort, int appid, String additionalQuery, long timeout, int maxsize, File cacheDir, boolean staleEnable);
其中:
httpHost,httpPort:auany http服务地址
appid:运营框架为该应用分配的id
additionalQuery:http代理服务器约定的查询参数
timeout, maxsize, cachedir, staleEnable:http服务请求参数,timeout决定了请求超时,maxsize约束了返回信息的最大尺寸,cacheDir提供了本地缓存目录,staleEnable决定了请求失败后是否使用本地缓存中的陈旧数据。
同一应用可能运行多个并列服务,所以返回List,其中的ServiceInfo,提供5个方法:
1. int[] getPvids();
获取该服务引用的pvid,顺序由auany配置决定。
2. int[] getPayids();
获取该服务的支付id,一般来说一个服务应该只有一个。
3. JSON[] getUserJSONs()
这里的JSON对象就是通过前面提到的JSONPublisher提供的,因为一个服务可能由多个provider提供,provider是否支持JSON通告是可选能力,所以这里返回JSON数组,数组尺寸与getPvids()返回的尺寸未必一致。
4. boolean isRunning()
该服务是否正在运行。
5. String getOptional()
这个方法与运营环境相关,返回运营环境为服务设定的特殊信息,例如,维护信息。
-
-
Auany配置
appconfig.xml提供了auany上的应用配置,该配置文件在系统运行过程中可以通过merge方式添加新的信息,而不需要停机维护。
-
switcher相关配置
<switcher host="127.0.0.1" id="1" key="abc" port="10000" type="native"/> <switcher host="127.0.0.1" id="2" key="abc" port="10001" type="ws"/>
auany内部的switcher与switcher服务的配置文件相对应,其中:
type:switcher类型,包括native,ws,wss三种,native对应limax网络服务,ws,wss对应WebSocket服务,其中wss支持ssl。
id:SwitcherId,在整个运营环境中唯一分配
key:与switcher服务器配置的key对应,用来认证switcher服务器。
host,port:switcher服务器对外服务的地址。
对照switcher服务器配置文件service-switcher.xml中Switcher条目:
<Switcher key="abc" …… > …………………………….. <native id="1"/> <ws id="2"/> </Switcher>
Switcher启动时,通过构造 { key, native-id[], ws-id[], wss-id[] } 信息向auany发起通告, 如果不能匹配auany中的配置信息, auany将命令switcher退出, 同时在switcher日志中报告错误原因。
注意:
1. 不同Switcher服务器应该配置不同key,避免id配置错误导致冲突。
2. 同一类型的Switcher服务可能存在多个,对应绑定不同的网络接口或者端口。
3. Switcher配置中的是否应该存在某种类型取决于接入服务的Manager配置。
4. auany配置中的host无法与Switcher配置中接入服务Manager下的localIp属性对应,因为无法确定Switcher之前是否存在NAT,这里的host必须填写真实的对外IP。
-
共享provider相关配置
<provider id="1" jsonPublishDelayMin="0" key=""/> <provider id="12" jsonPublishDelayMin="0" key=""/>
id:ProviderId,运营环境内部全局唯一。
key:provider的key,用以验证provider服务合法性,与Provider配置中的key对应。
jsonPublishDelayMin:该provider的两次JSON对象请求之间的最小时间间隔,为0表示禁止该provider发布JSON信息。
共享provider被应用配置中的app条目,或者之下的service条目引用。
没有被任何app或者service引用的provider为可选的共享provider,客户端登录时可以请求这样的provider进行服务,也可以不请求。其中provider id=1被Auany保留, 提供AuanyService。
-
应用配置
<app id="1" jsonPublishDelayMin="15000" maxSubordinates="0" providerMatchBidirectionally="true" shareProvider=""> <service id="1" shareProvider="" switcher="1,2,3"> <provider id="100" key=""/> </service> </app> <app id="2" jsonPublishDelayMin="5000" maxSubordinates="8" providerMatchBidirectionally="true" shareProvider="12"> <service id="1" shareProvider="" switcher="1,2,3"> <provider id="200" key=""/> </service> <service id="2" shareProvider="" switcher="1,2,3"> <provider id="300" key=""/> </service> </app>
app节点:
<app id="1" jsonPublishDelayMin="15000" maxSubordinates="0" providerMatchBidirectionally="true" shareProvider="">
id:应用id,运营环境内部全局唯一。
jsonPublishDelayMin:该应用中使用的公共Provider之外的所有私有Provider的JSON对象发布时间间隔。
maxSubordinates:该应用支持的最大子账号数,为0表示禁止使用子账号。
providerMatchBidirectionally:provider列表双向匹配,如果为true,请求的provider列表与配置的provider列表双向匹配;如果为false,允许请求配置provider列表的非空子集。
shareProvider:逗号分隔的共享ProviderId列表,禁止引用Auany服务的id(=1)。
service节点:
<service id="1" shareProvider="" switcher="1,2,3">
id:服务id,一个应用配置下保证唯一。
shareProvider:逗号分隔的共享ProviderId,禁止引用Auany服务的id(=1)。
switcher:逗号分隔的SwitcherId列表。
私有provider节点:
<provider id="200" key=""/>
类比共享provider节点,这里缺少jsonPublishDelayMin属性,该属性继承自app节点。
注意:
1. 共享provider,私有provider在同一分配域中分配id,也就是说共享provider,私有provider的id之间也不允许冲突。
2. 客户端向服务器发起应用信息请求,最重要的信息就是下一步需要连接的switcher地址,auany只通告已经启动的switcher,如果配置文件中配置了,但是实际的Switcher服务没有启动,对应的配置地址不会通告。如果service中相应type的所有Switcher服务都没有启动,则通告的服务运行状态一定为false。
3. 服务信息中pvid通告顺序由私有provider列表,service引用的共享Provider列表,app引用的共享provider列表决定。
4. 如果一个服务引用的provider没有全部启动,则通告的服务运行状态为false。
-
添加新的服务配置
auany配置文件中,Auany节点中两个属性
appConfigPatch:服务patch文件名,默认为appnew.xml
appConfigPatchCheckPeriod:服务patch文件检测周期,默认30000,即30秒
具体操作:
1. 建立一个格式与appconfig.xml相同的配置文件appnew.xml。其中, 可以创建新的switcher, 新的共享provider, 新的app, 已经存在app中新的service, 只要不存在id冲突即可。
2. 将appnew.xml拷贝到appconfig.xml相同目录下,最迟30秒,appnew.xml被改名为appnew.xml.result,文件尾部追加了merge结果信息。
3. 如果成功,新的配置被装载进auany服务,appnew.xml被merge到appconfig.xml中,原来的appconfig.xml备份为appconfig.xml.bak。
4. 如果失败,追加的merge结果信息指出了错误原因,比如操作异常,id冲突,这种情况下正在运行的服务不受影响,appconfig.xml没有改变。
-
更新具体服务的Optional信息
public interface AppManagerMXBean { void setServiceOptional(int appid, int serviceid, String optional); }
通过访问Auany的JMX服务,以appid,serviceid为key, optional为value,调用setServiceOptional方法。之后,相应的Endpoint上通过ServiceInfo.getOptional()即可取得该信息。
-
注意事项
1. 应用应该通过自己的JSON通告提供服务名之类的信息,不要过度依赖auany通告的服务信息,一种典型的实现是创建一个map,提取JSON通告的应用服务信息作为key去索引通告返回的ServiceInfo。
2. Endpoint提供的各种与switcher ip,switcher port相关的请求接口都提供了对应的ServiceInfo版本, 使用ServiceInfo前, 必须判断服务是否处于运行状态, 避免产生运行时错误。
3. 大运营环境下,为了降低auany http服务负荷,可以部署http代理服务器进行加速。
-