1、源代码
normandy.shared.trunk:
svn co http://svn.alibaba-inc.com/repos/ali_platform/normandy/shared/trunk
normandy.server:
svn co http://svn.alibaba-inc.com/repos/ali_platform/normandy/app/server/trunk/normandy.server
2、数据库
10.20.36.26开发库 10.20.129.167测试库 normandy/normandy,Schema:normandy_dev/normandy_test
对用户授权:
GRANT ALL PRIVILEGES ON *.* TO 'normandy'@'localhost' IDENTIFIED BY 'normandy' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'normandy'@'%' IDENTIFIED BY 'normandy' WITH GRANT OPTION;
3、编译以及环境搭建
<1> 先编译normandy.shared.trun, 再编译normandy.server, 最后在normandy.server/target/normandy.server-0.1.0/bin下面使用./start-normandy.sh进行启动。
<2>以debug的方式启动程序
./
start-normandy.sh debug
debug启动端口 normandy.server.debug.port = 9020
<3>以Debug方式远程调试程序
首先:必须使用debug参数开启debug端口9020
其次:在入口server的ConfigServiceImpl类的方法上面设置断点, 远程连接服务器
最后,在程序中以java或者debug方式启动客户端(即客户端是否需要开启debug模式,与服务器是否是debug模式没关系;同样服务端是否开启debug与客户端是否开启也没关系),则此时会在设置断点的地方停止下来等待继续。
断开远程端口:在eclipse的debug视图下面,点击类时出现红色的‘Terminal’按钮即可。
4、提供的服务
5、架构分析
6、业务
【注意】
1、注意数据的正确性
config_key, config_value
2、对Transaction进行事务各种管理,方便测试
首先:添加依赖管理
- <dependency>
- <groupId>com.alibaba.external</groupId>
- <artifactId>sourceforge.spring.modules.aspects</artifactId>
- <version>2.5.6</version>
- </dependency>
其次:增加切面方法
- package com.alibaba.normandy.server.core.service.util;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.After;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- @Aspect
- public class TransactionInjectionServiceUtil {
- @Pointcut("execution(public * com.alibaba.normandy.server.core.service.impl.*.*(..))")
- private void pointcutService(){
- }
- @Pointcut("execution(public * com.alibaba.normandy.server.core.service.dao.*.*(..))")
- private void pointcutDao(){
- }
- @Before("pointcutService()")
- public void beforeServiceActions(){
- //before action
- System.out.println("beforeServiceActions invoked!");
- }
- @After("pointcutService()")
- public void afterServiceActions(){
- //after action
- System.out.println("afterServiceActions invoked!");
- }
- @Around("pointcutService()")
- public void aroundServiceActions(ProceedingJoinPoint pjp){
- //before action
- System.out.println("before aroundServiceActions invoked!");
- try {
- pjp.proceed();
- } catch (Throwable e) {
- e.printStackTrace();
- }
- //after action
- System.out.println("after aroundServiceActions invoked!");
- }
- @AfterThrowing("pointcutService()")
- public void exceptionServiceActions(){
- System.out.println("exceptionServiceActions invoked!");
- throw new RuntimeException("exception in service, will rollback!");
- }
- }
增加配置文件:normandy-transactionService-aop.xml,在配置文件中添加如下配置
- <aop:aspectj-autoproxy />
- <bean id="transactionInjectionServiceUtil" class="com.alibaba.normandy.server.core.service.util.TransactionInjectionServiceUtil" />
在整个容器的加载地方指定要加载normandy-transactionService-aop.xml配置文件。在applicationContext-normandy-server.xml中进行添加:
- <import resource="classpath:spring/normandy-transactionService-aop.xml" />
最后:启动server服务器端,再开始远程调用
3、在pub时,必须要先创建application和domain的记录
例如:minas@us-domain:alibaba.platform.minas.basic.setting.workdir, 其中application为:minas, domain为:us-domain, 后面为真正的key值。 每次发布时,整个长度限制在255个字符之内,一般情况下是以'.'进行分割,也可以支持'_'。
4、定点推送
在发布的时候可以先考虑定点推送一个k/v给某台机器的某个端口进行验证,如果成功则可以大规模的推送到整个集群中。使用方法如下:
String addressList = "10.20.30.40:8080"; client.publish(key, value,
addressList);
(1)定点发布只修改config_value_change_event表,而不修改config_key和config_value表。
(2)其中的fired_server_ip字段记录了normandy集群中完成publish机器的server的ip地址。
5、发布保证最终的一致性
pub的的key/value键值对,会保证最终的一致性,但是需要处理经历事件的过程,正常情况在5秒之内完成。所以意味着:马上发的,马上去订阅可能订阅不了。
6、在多个client同时不断发布同一个Key,不同的value时,可能存在异常:com.alibaba.normandy.server.core.service.exception.ConcurrentConflictException:
这是由于获取了version之后都做插入的动作。服务器不应该去决定服务器是否重试,而是应该为客户端抛出异常,由客户端来做处理。
7、数据库设计
select APPLICATION_ID, DOMAIN_ID,
uid,AGGREGATE_TYPE,enabled,
globe_uid from config_key;
select CONFIG_KEY_ID,
value,type,VERSION,publisher from config_value;
application:关于应用的内容,例如dubbo、napoli
domain:关于域的内容,例如:杭州域 hz-domain或者美国域 us-domain
normandy_server:关于normandy server自身的相关信息,其中
status的含义为:
1表示normandy server为stop,2表示normandy server为start,3为overlapped,但是3不会写到数据库。
8、normandy server允许连接数设置
在配置文件normandy-server-core-services.xml中有参数${connection.maxConnectionCount}
在antx.properties中,通过normandy.server.connection.max.count进行传递
9、多线程下面publish场景,出现java.util.ConcurrentModificationException
非append接口,直接抛给客户端
如果是append接口,server负责重试到成功为止
10、由于publish和publishAppend的语义的区别,所以不允许放在一起针对同一个key进行使用。
publish:config_value的type字段为
com.alibaba.normandy.common.domain.SimpleConfigValue,publisher值为
发布者ip:端口
publishAppend:config_value的type字段为
com.alibaba.normandy.common.domain.CombinedConfigValue,publisher值为
serverip:端口-
发布者ip:端口+uid
11、联合查询
查询application、domain、key、value:
select a.name, d.name, uid, value , version
from domain d, application a, config_key k, config_value v where k.id = v.CONFIG_KEY_ID;
select a.name, d.name, uid, value, version from domain d, application a, config_key k, config_value v where k.id = v.CONFIG_KEY_ID;
12、normandy的key、value长度限制:2011-06-23
(1)调整key长度范围为255,而不是256
(2)config_key表的uid长度为200(key去除domain、application、@、:后剩下的部分),存在问题,需要修改为255
(3)value设置较大时,例如长度为2048时,则触发了dubbo的重连,存在并发修改异常;或者触发ProtocolClientException
本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/561642,如需转载请自行联系原作者