发表于: 2018-01-31 22:40:34
1 743
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
学习是日渐变水了,到晚上才想起做任务...
跟上昨天的计划,实现1web对应多server.有些时候想法很简单,真正实施起来是真的难.
我目前完成了在运行期间随机切换,以及其中一台服务器宕机后不影响使用.
server端配置2个相同的服务,以不同的端口注册RMI服务即可.
然后是web端口,web端就比较麻烦.因为当一个服务器宕机之后,spring会抛出一个异常,而这个异常是在生成applicationContext容器的时候抛出的.也就是说我们想要捕捉到宕机这个异常并处理就需要反复的去重新读取这个容器,不然这个异常你通过bean类去捕捉是捉不到的, 虽然触发这个异常是你的bean,但是抛出异常的却是容器.下面看一下我的代码.
package com.util;
import com.service.IService;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
/**
* @author Arike
* Create_at 2018/1/31 18:00
*/
//解决思路有点智障.每次运行都会去默认加载配置文件,就是为了捕捉一个服务器挂掉的异常.这样会增加整个请求响应的时间
@Component
public class ServerUtil {
private Logger logger = Logger.getLogger(ServerUtil.class);
private int num;
private int status;
private ApplicationContext appA;
private ApplicationContext appB;
private void getAppA() {
if (status != 1) {
status = 1;
this.appA = new ClassPathXmlApplicationContext("spring-serverA.xml");
}
}
private void getAppB() {
if (status != 1) {
status = 1;
this.appB = new ClassPathXmlApplicationContext("spring-serverB.xml");
}
}
public IService getService() {
int i = (int) (Math.random() * 10);
if (num == 0) {
if (i % 2 == 0) {
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-serverA.xml");
logger.info("正常使用serverA");
return ctx.getBean(IService.class);
} catch (Throwable e) {
num = 2;
getAppB();
logger.info("serverA挂了,捕捉异常使用serverB");
return appB.getBean(IService.class);
}
}
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-serverB.xml");
logger.info("正常使用serverB");
return ctx.getBean(IService.class);
} catch (Throwable e) {
num = 1;
getAppA();
logger.info("serverB挂了,捕捉异常使用serverA");
return appA.getBean(IService.class);
}
}
if (num == 1) {
logger.info("异常处理使用serverA");
return appA.getBean(IService.class);
}
if (num == 2) {
logger.info("异常处理后serverB");
return appB.getBean(IService.class);
}
return null;
}
}
代码里我对2个配置在服务器完好的时候进行反复加载,每次获取不同的服务就会重新加载一次,这个是对请求响应时间的一个大影响,平时只需要0.1秒左右响应的请求,现在加上这个反复轮询之后需要0.5~0.8秒才能响应回去,客户体验极差. 但是在一台服务器挂掉捕捉到异常之后,我可以判断到只有一个配置了,这个时候只会去加载一次配置,反而又回到0.1秒的响应时间,如此就显得很畸形.所以我的新的处理思路是如下:
1.spring本身有一套异常处理机制,打算学习一下,看是否能抓住这个异常.
2.监听器貌似也有一个捕捉容器出错的方法,如果异常机制不能完成,就从监听器入手.
另外昨晚测试各种方式捕捉异常也搞到了两三点,,虽然有点鸡肋,还是跑一下把,毕竟功能实现了..
先后开启2个server.
serverA
serverB
最后是客户端:
另外因为客户端的spring配置文件多了一份,需要也加入web.xml里面
接下来是尝试:
到网页随意进行操作,看一下client的日志:
只截了2次请求在Server间的切换,可以看到,这延迟,刚刚的要命.
然后接下来关闭其中一台服务器,模拟宕机效果.我这里关闭服务器A.
再进行页面操作:
我执行第二次请求就随机分发到了serverA,但此时A已经宕机了,捕捉到异常进入到serverB,并打出日志告知服务器A挂了.
然后继续执行.
可以看到每次请求都会发送给B执行,然后这个延迟,基本不会超过0.2 .再和之前出现异常的时候比较.简直扎心.
不过怎么说,功能要求实现了,就剩优化了.
明天计划的事情:(一定要写非常细致的内容)
明天就得回家了,5号再上来,不过这次任务让我来了兴趣,打算在家里把这个分布式完善了,然后把任务9也搞定.
遇到的问题:(遇到什么困难,怎么解决的)
问题真的是太多太多....我写在日报里的不足十分之一....
我尝试过客户端使用原生RMI Naming的方式去捕捉服务器的远程服务,结果万万没想到,捕捉下来的并不是直接的service实现类,而是spring中转的一个容器类, 然后这个容器类又封装了N层..看的我头晕,在尝试了N久的方法捕捉和强转都没法拿到我们准确的senrvice,各种强转失败....
还有问题还多,就不一一赘述了
收获:(通过今天的学习,学到了什么知识)
异常处理博大精深,得好好学习.
另外去看了一下上海分院的成延的日报,别人每天都是高强度十多个小时学习,1个多月就完成任务出去工作.而转头看看自己...
每天学习的时间超不过5个小时........shame..想想自己要是一直劲头那么大,估计也早就做完了...
评论