发表于: 2018-03-15 21:51:56
2 534
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
对任务8要求随机服务器宕机进行了重新设计.
package com.listener;
import com.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author: Arike
* @program: task8-server
* @description: 用于加载容器之后需要执行的代码, 只要容器加载完成之后就会加载.会比bean注解listener慢一点, 因为除非是懒加载, bean总是早于容器完成的.
* @create: 2018/2/28 11:36
*/
@Component
public class MyListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
RedisUtil redisUtil;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null) {
//root application context 没有parent,他就是老大.
//需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
System.setProperty("java.rmi.server.hostname", "120.79.4.239");
System.out.println("你好");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
redisUtil.put("ServerA", "ServerA","ServerA", 1L);
System.out.println("添加A的缓存");
}
}, 100, 1000);
}
}
}
具体思路是这样,用缓存来做标记,server每一秒往redis里插入一个生命周期为1s的缓存,请求服务之前先去缓存找相应server的标记,找到再请求,server挂了的话这个缓存就没了,就过滤到这个server。
这是客户端随机访问的代码:
@Autowired
ApplicationContext ctx;
@Autowired
RedisUtil redisUtil;
public IService getService() {
IService A;
IService B;
int i = (int) (Math.random() * 10);
if (i % 2 == 0) {
if (redisUtil.haskey("ServerA", "ServerA")) {
System.out.println("正常访问A服务");
A = ctx.getBean("rmiServerA", IService.class);
return A;
} else {
System.out.println("随机到A,A已挂,转向B");
B = ctx.getBean("rmiServerB", IService.class);
return B;
}
} else {
// try {
// B = ctx.getBean("rmiServerB", IService.class);
// return B;
// } catch (BeansException e) {
//
// }
if (redisUtil.haskey("ServerB", "ServerB")) {
System.out.println("正常访问B服务");
B = ctx.getBean("rmiServerB", IService.class);
return B;
} else {
System.out.println("随机到B,B已挂,转向A");
A = ctx.getBean("rmiServerA", IService.class);
return A;
}
}
}
}
然后运行进行测试:
web端进行测试:
可以看到的是能够在2台Server之间随机切换.然后模拟一下宕机效果.我关闭了A服务器
可以清楚的看到到再次分配到A服务器的时候,因为缓存中已经没有来自于A服务的标记,所以就直接转向了B服务.
另外也有可能出现有用户在验证的时候通过了,然后服务器宕机的情况,这种时候就得异常捕捉下来,然后重新调用用户的请求.
另外跟老大讨论过,老大提出的思路还是之前说的,让在服务上捕捉异常就可以了,不用这么麻烦.
可是这个服务器宕机的异常是在applicationContext生成的时候抛出. 也就是只能通过try catch
ApplicationContext a = new ClassPathXmlApplicationContext("spring-serverA.xml");
这段代码捕捉到,我尝试过try catch其他的任何语句都捕捉不到这个异常,这样的确更简单,但是反复加载spring这个配置文件,一个响应的请求时间会达到700ms以上,我个人觉得这样很蠢. 不知道师兄有什么思路.
另外使用spring异常处理来统一抓这个异常也不好使, 因为不管哪个服务器宕机了,他抛出的异常都是同一个.
捕捉到了也不能判断是哪个服务器挂了.
另外下午的时候用我们项目的表格尝试的生成了一下代码,发现了很多问题..
表格的自增长ID字段名称必须为ID,不然生成的查询语句都得去改.
明天计划的事情:(一定要写非常细致的内容)
用公司框架先把所有的底子生成,进行项目内容的分工.
遇到的问题:(遇到什么困难,怎么解决的)
上面已经描述.
收获:(通过今天的学习,学到了什么知识)
对监听器和定时任务又回顾了一次.
评论