发表于: 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。


明天计划完成的事情:

深度思考,按师兄的建议找一个分布式框架看看。


返回列表 返回列表
评论

    分享到