发表于: 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,不然生成的查询语句都得去改.


明天计划的事情:(一定要写非常细致的内容) 

用公司框架先把所有的底子生成,进行项目内容的分工.


遇到的问题:(遇到什么困难,怎么解决的) 

上面已经描述.
收获:(通过今天的学习,学到了什么知识)

对监听器和定时任务又回顾了一次.


返回列表 返回列表
评论

    分享到