发表于: 2017-09-08 21:17:52

1 880


一.今天完成的主要事情

1.配置负载均衡,整体策略是使用两台服务器,整体部署图如下

域名----->nginx服务器------>服务器A的web端------------->随机访问服务器A或服务器B的service

                      |

                      |---------------->服务器B的web端------------->随机访问服务器A或服务器B的service

这里画的很简陋,但是web在调用service时,不一定调用同一个服务器上的service,也会访问另一台服务器上的service

具体做法就是,先将代码上传到服务器(通过打包或者svn上传),然后再服务器端根据需要更改相应的配置,然后运行service和web,接着用Jmeter

测试看是否成功

结果:一开始测试正常,没有贴图

然后关闭服务器A的服务

然后再关闭服务器B的web端

通过测试可以看到,只要有一个web以及service运行,程序就不会挂,完成了任务要求

2.优化昨天日报中提到的多例模式的性能问题

这个解决方式是和王蒙在相互讨论摸索出来的(主要是王蒙想的).

首先,依然是两个xml配置文件,一个配置文件对应一个服务

其次,将随机选择注册bean的代码抽取出来封装为一个类,然后再controller的类中调用该类,因为controller是单例的,那么该类也是唯一的.这样,如果将注册bean的操作放在该类的构造方法中,那么该注册到的bean就是唯一的,但这样做也会有缺陷,那么就是如果一个服务挂了,由于只注册了一次,那么服务也就跟着挂掉了,解决方式就是在controller中捕捉服务挂掉时的异常,然后再次注册一次即可.

首先是自定义CallService类代码:

//构造方法中先注册一次,如果服务没有挂,那么一直使用该服务

public CallService(){

ApplicationContext context = registratContext();
this.userDaoServiceRemote =
(UserDaoServiceRemote) context.getBean("rmiProxyUser");
this.studentDaoServiceRemote =
(StudentDaoServiceRemote) context.getBean("rmiProxyStudent");
}
//该方法是随机注册bean的实现,返回ApplicationContext对象
private ApplicationContext registratContext(){
Random random = new Random();
ApplicationContext context;
//捕捉BeanCreationException,如果发现该异常,说明该服务被中断,转向另一个服务
   if (random.nextInt(10) % 2 == 0) {
try {
context = new ClassPathXmlApplicationContext("remote-context-1.xml");
} catch (BeanCreationException e) {
context = new ClassPathXmlApplicationContext("remote-context-2.xml");
}
} else {
try {
context = new ClassPathXmlApplicationContext("remote-context-2.xml");
} catch (BeanCreationException e) {
context = new ClassPathXmlApplicationContext("remote-context-1.xml");
}
}

return context;
}
//如果其中一个服务挂掉,捕捉到异常之后调用该方法,再次随机注册bean
public void getBeanAgain(){
ApplicationContext context = registratContext();
this.userDaoServiceRemote =
(UserDaoServiceRemote) context.getBean("rmiProxyUser");
this.studentDaoServiceRemote =
(StudentDaoServiceRemote) context.getBean("rmiProxyStudent");

}

控制器中的代码如下(只贴出一个方法中的,其他的类似):

先创建唯一的一个CallService对象

在各个方法中使用该对象获取相应的远程注册对象

// 所有学生列表
@RequestMapping(value = "/u/list", method = RequestMethod.GET)
public String findAll(Model model) {


try{

//先尝试获取一次,如果获取成功,则继续执行业务逻辑

this.studentDaoServiceRemote = callService.getStudentDaoServiceRemote();

}catch(RemoteConnectFailureException e){ //如果注册失败,则捕捉RemoteConnectFailureException异常,并在处理时再次注册获取一次,此时只要有一个服务是正常的,就能获取到相应的对象

callService.getBeanAgain();
this.studentDaoServiceRemote = callService.getStudentDaoServiceRemote();
}
List<BasicVo> list = studentDaoServiceRemote.findAll();

model.addAttribute("studentList", list);
return "studentList";
}

经过测试,这种方式比昨天的多例模式效率高了近三倍,有测试截图为证:

同样是服务在服务器,web在本地,吞吐量提高了三倍,原来只能在10/sec左右

但解决问题的同时也要注意,该方法没有经过完整的测试,所以有可能会出现bug,这里只作为作任务时的测试使用

二.明天计划完成的事情

1.完成深度思考

2.开始任务九,学习Tuscany

三.遇到的问题

暂无

四,收获

以上

五,任务进度情况

无延期风险,今日已经提交任务



返回列表 返回列表
评论

    分享到