发表于: 2017-09-21 23:50:00
1 807
【今日完成】
今天继续任务八。
昨天跑通了RMI的一个小Demo。
今天就在考虑模拟两个服务器的情况。来让客户端随机访问服务器,调用对应服务器的方法。
具体的想法是这样的:
配置两个服务xml,配置两个客户xml
让客户端随机访问服务器,调用方法。
先看两个客户端xml配置文件
Client1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="Example" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:11097/ITestMethod" />
<property name="serviceInterface" value="Service.ITestMethod" />
</bean>
</beans>
Client2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="Example" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:11010/ITestMethod" />
<property name="serviceInterface" value="Service.ITestMethod" />
</bean>
</beans>
可以看到两个文件只是端口不一样,其余都一样。
然后是两个服务端配置:
Server.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="serviceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="ITestMethod" />
<property name="service" ref="Example" />
<property name="serviceInterface" value="Service.ITestMethod" />
<property name="registryPort" value="11097" />
<property name="servicePort" value="11097" />
<!--端口11097-->
</bean>
<bean id="Example" class="Service.Example" />
</beans>
Server2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="serviceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="ITestMethod" />
<property name="service" ref="Example" />
<property name="serviceInterface" value="Service.ITestMethod" />
<property name="registryPort" value="11010" />
<property name="servicePort" value="11010" />
<!--自定义端口11010-->
</bean>
<bean id="Example" class="Service.Example" />
</beans>
就这样两套配置文件成型。
然后是Controller
当路径为/one,会new 一个上下文工厂,用了Server.xml ------>对应服务器一
当路径为/two,会new 一个上下文工厂,用了Server2.xml ------>对应服务器二
package controller;
import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class task8controller {
static final Logger LOG =Logger.getLogger(task8controller.class);
@RequestMapping(value = "/one")
public String one() throws InterruptedException{
new ClassPathXmlApplicationContext("Server.xml");
LOG.info("服务器一");
return "one";
}
@RequestMapping(value = "/two")
public String two() throws InterruptedException{
new ClassPathXmlApplicationContext("Server2.xml");
LOG.info("服务器二");
return "two";
}
}
最后是客户端:
可以看到先是生成了一个Random数,乘以10后范围为0~9
当为奇数时,生成一个客户端,调用服务器一
当为偶数时,生成一个客户端,调用服务器二
当然,为了使一个服务器挂掉也能正常执行,特地用了一个Try。。。Catch语句块。
把BeanCreationException异常接住,调用另一个服务器(比如一开始调用服务器一,catch里面就会调用服务器二)
package core;
import Service.ITestMethod;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Random;
public class RmiClient {
private static final Logger LOG = Logger.getLogger(RmiClient.class);
public static void main(String[] args) {
double m =Math.random();
int rr =(int)(m*10);
if(rr%2!=0) {
try{ApplicationContext ctx = new ClassPathXmlApplicationContext(
"client.xml");
ITestMethod testMethod = (ITestMethod) ctx.getBean("Example");
String result = testMethod.sayHi("龚剑飞from服务器一");
LOG.info(result);}
catch (BeanCreationException e){
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"client2.xml");
ITestMethod testMethod = (ITestMethod) ctx.getBean("Example");
String result = testMethod.sayHi("龚剑飞from服务器二");
LOG.info(result);
}
}else {
try{ApplicationContext ctx = new ClassPathXmlApplicationContext(
"client2.xml");
ITestMethod testMethod = (ITestMethod) ctx.getBean("Example");
String result = testMethod.sayHi("龚剑飞from服务器二");
LOG.info(result);}
catch (BeanCreationException e){
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"client.xml");
ITestMethod testMethod = (ITestMethod) ctx.getBean("Example");
String result = testMethod.sayHi("龚剑飞from服务器一");
LOG.info(result);
}
}
}
}
废话不多说,来看看结果:
首先我不开服务器,直接用客户端调用方法
不出意外,连接被拒绝,挂了
然后我开服务器
注意这里配了两个Tomcat来模拟两个服务器
可以看到两个服务器都开启了。现在来调用方法
成功,来自服务器一,随机数生成为了奇数
多执行了几次后,可以看到这里来自服务器二,随机数生成了偶数
好,那么我们关掉一个服务器:
就关服务器一吧
直接关掉它,继续来演示
这个时候看,服务器二是开启的,那么随机数为偶数时,直接调用服务器二的方法,
可以看到和前面并没有什么不一样。
那么最关键的来了,此时服务器一已经挂了,如果随机数为奇数,会直接访问服务器一的方法
这时候能不能正常访问呢?
可以看到,这里明显多打印了几行,仔细看中间那一行:
Connection refused,连接被拒绝。
这就是程序一开始想调用服务器一的方法,但服务器一已经关闭了,
这时候本来该报异常,但catch住了,
让其调用服务器二,服务器二还没被我关掉,这时候还可以正常调用。
所以流程是先访问服务器一,发现关掉了,无法连接,然后访问服务器二,可以正常执行。
最后我再把服务器二也关了,看看如何:
不出意外报错了,两个都无法访问,这就只能报错了。
【今日收获】
用两个Tomcat来模拟两个服务器
一个挂掉了,另一个照常运行,不碍事
【明日计划】
看看Nginx
【任务进度】
无延期风险
评论