发表于: 2020-07-18 23:58:23
1 1288
今天完成的事情:
在原来的WEB中调用Service:
配置spring配置文件:
<!--RMI客户端-->
<bean id="rmiProxyFactory1" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/AccountServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.AccountService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory2" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/StudentServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.StudentService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory3" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/ProfessionServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.ProfessionService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
先启动服务器端的Service:
然后启动客户端的WEB,可以正常访问,同时服务器端输出日志可以证明调用的是服务器端的service:
接下来部署两台Service,在WEB中随机访问任意一台Service。
我这里直接在本地部署一台Service,在服务器部署一台。
要在WEB中随机访问任意一台Service:
我的想法是随机生成一个数字0或1.如果为1则访问service1,如果为0则访问service2,具体代码:
@org.junit.Test
public void server(){
Random random = new Random();
int i = random.nextInt(2);
System.out.println(i);
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
if(i==1){
System.out.println("从server1获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory2");
}else{
System.out.println("从server2获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory22");
}
System.out.println(studentService);
System.out.println(studentService.selectStudent());
}
效果如下:
可以看到地址分别是本地和远程服务器。
优化一下,对异常进行处理,在一台service挂了的时候使用另外一台service:
@RequestMapping(value = "home",method = RequestMethod.GET)
public String getIndex(Model model){
Random random = new Random();
int i = random.nextInt(2);
System.out.println(i);
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
if(i==1){
try{
System.out.println("从server1获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory2");
}catch (Exception e){
try {
System.out.println("从server1获取失败,转向从server2获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory22");
}catch (Exception e1){
System.out.println("获取失败,两个服务器都挂了。。。");
return "index";
}
}
}else{
try{
System.out.println("从server2获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory22");
}catch (Exception e){
try{
System.out.println("从server2获取失败,转向从server1获取。。。");
studentService =(StudentService)context.getBean("rmiProxyFactory2");
}catch (Exception e1){
System.out.println("获取失败,两个服务器都挂了。。。");
return "index";
}
}
}
List<Student> studentList = studentService.selectStudent();//查询优秀学员
Integer count = studentService.selectByLearning();//累计在线学习人数
Integer number = studentService.selectByWorking();//已找到工作的学员
model.addAttribute("studentlist",studentList);
model.addAttribute("count",count);
model.addAttribute("number",number);
return "myView";
}
运行结果:
成功实现,但是好像有点问题,如果随机到挂了的那台服务器的话,请求耗时非常大,我猜想会不会是因为我这里spring使用的懒加载(lazy-init)配置,在请求的时候才创建bean,然后由于其中一台service挂了所以创建bean失败转而创建另一个service的bean,这个过程比较费时间。
但是如果不使用懒加载的话在配置文件加载的时候就会报错了,也没办法实现后面的功能了。不知道这个现象正不正常,有没有更好的解决办法。
然后是部署两台WEB,通过Nginx配置两台WEB随机访问,两台WEB可以随机访问两台Service。
这里为了方便起见,直接设置两台服务端的不同端口号的service来模拟两台service:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:db.properties" />
<!--开启注解自动扫描-->
<context:component-scan base-package="com.jnshu"/>
<!-- 配置连接数据库的数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"/>
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="url" value="${url}"/>
</bean>
<!-- 引入数据源和mybatis全局配置文件-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:Mybatis-config.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jnshu.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--配置spring开启注解AOP的支持-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<import resource="memcached.xml"/>
<!-- RMI服务端A -->
<!-- RMI服务端远程接口实现类 -->
<bean id="accountServiceImpl" class="com.jnshu.service.AccountServiceImpl" scope="prototype"/>
<bean class="com.jnshu.Server.OwnRmi">
<!-- 将远程接口实现类对象设置到RMI服务中 -->
<property name="service" ref="accountServiceImpl"/>
<!-- 设置RMI服务名,为RMI客户端依据此服务名获取远程接口实现类对象引用奠定基础 -->
<property name="serviceName" value="AccountServiceImpl"/>
<!-- 将远程接口设置为RMI服务接口 -->
<property name="serviceInterface" value="com.jnshu.service.AccountService"/>
<property name="registryHost" value="localhost"/>
<!-- 为RMI服务端远程对象注册表设置端口号-->
<property name="registryPort" value="1111"/>
</bean>
<bean class="com.jnshu.Server.OwnRmi">
<property name="service" ref="studentServiceImpl"/>
<property name="serviceName" value="StudentServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.service.StudentService"/>
<property name="registryHost" value="localhost"/>
<property name="registryPort" value="1111"/>
</bean>
<bean class="com.jnshu.Server.OwnRmi">
<property name="service" ref="professionServiceImpl"/>
<property name="serviceName" value="ProfessionServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.service.ProfessionService"/>
<property name="registryHost" value="localhost"/>
<property name="registryPort" value="1111"/>
</bean>
<!--=====================================================================================-->
<!-- RMI服务端B -->
<!-- RMI服务端远程接口实现类 -->
<bean class="com.jnshu.Server.OwnRmi">
<!-- 将远程接口实现类对象设置到RMI服务中 -->
<property name="service" ref="accountServiceImpl"/>
<!-- 设置RMI服务名,为RMI客户端依据此服务名获取远程接口实现类对象引用奠定基础 -->
<property name="serviceName" value="AccountServiceImpl"/>
<!-- 将远程接口设置为RMI服务接口 -->
<property name="serviceInterface" value="com.jnshu.service.AccountService"/>
<property name="registryHost" value="localhost"/>
<!-- 为RMI服务端远程对象注册表设置端口号-->
<property name="registryPort" value="2222"/>
</bean>
<bean class="com.jnshu.Server.OwnRmi">
<property name="service" ref="studentServiceImpl"/>
<property name="serviceName" value="StudentServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.service.StudentService"/>
<property name="registryHost" value="localhost"/>
<property name="registryPort" value="2222"/>
</bean>
<bean class="com.jnshu.Server.OwnRmi">
<property name="service" ref="professionServiceImpl"/>
<property name="serviceName" value="ProfessionServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.service.ProfessionService"/>
<property name="registryHost" value="localhost"/>
<property name="registryPort" value="2222"/>
</bean>
</beans>
然后WEB端也作相应修改:
<bean id="rmiProxyFactory1" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/AccountServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.AccountService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory11" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:2222/AccountServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.AccountService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory2" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/StudentServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.StudentService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory22" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:2222/StudentServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.StudentService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory3" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:1111/ProfessionServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.ProfessionService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
<bean id="rmiProxyFactory33" class="org.springframework.remoting.rmi.RmiProxyFactoryBean" lazy-init="true">
<property name="serviceUrl" value="rmi://81.68.101.220:2222/ProfessionServiceImpl"/>
<property name="serviceInterface" value="com.jnshu.Service.ProfessionService"/>
<!--当连接失败时是否刷新远程调用stub-->
<property name="refreshStubOnConnectFailure" value="true"/>
</bean>
运行效果如下:
可以正常运行。
然后将它分部署到服务器上的tomcat和resin中,使用nginx部署它们随机访问。
这里配置nginx的时候有个坑,单独访问两台WEB都可以,但是使用nginx之后会有一个web报400错误。在网上查了之后好像是由于后端服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能。
所以必须加上:
之后就正常了,nginx可以随机访问两台WEB,然后两台WEB又可以随机访问两台Service。
任务八基本做完了。
收获:学会了一个WEB访问多个Service,多个WEB交叉访问多个Service。
明天计划完成的事情:
深度思考,按师兄的建议找一个分布式框架看看。
评论