发表于: 2019-10-18 21:07:23

2 4200


一、今天完成的事
1.解决昨天报错的问题
原来我的@service没有删掉
删掉之后再检查applicationContext
发现我之前没有这个行
<!--Dao接口所在包名,spring会扫描basePackage并自动装配-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.ksy.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
再次运行
服务端启动成功
再去启动客户端
sqlSession注入失败,检查客户端删掉dao接口
删掉之后再运行
没有问题
2.使用try/catch方法实现随机访问两个服务端
if (RandomUtil.randomCode() == 0) {
    try {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("/spring/server1.xml");
        studentService = (StudentService) applicationContext.getBean("student1");
        log.info("服务1.0启动");
    } catch (Exception e) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("/spring/server2.xml");
        studentService = (StudentService) applicationContext.getBean("student2");
        log.info("服务2.0启动");
    }
} else {
    try {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("/spring/server2.xml");
        studentService = (StudentService) applicationContext.getBean("student2");
        log.info("服务2.1启动");
    } catch (Exception e) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("/spring/server1.xml");
        studentService = (StudentService) applicationContext.getBean("student1");
        log.info("服务1.1启动");
    }
}
这个方法修改比较麻烦,而且每个controller都写的话显得程序比较夯杂。
改用第二种方法

cluster4spring开源的第三方jar包,可以随机的访问服务

mvn install:install-file -Dfile=E:\cluster4spring-1.0.2.jar -DgroupId=com.cluster4spring -DartifactId=cluster4spring -Dversion=1.0.2 -Dpackaging=jar
<!--cluster4spring-->
<dependency>
<groupId>com.cluster4spring</groupId>
<artifactId>cluster4spring</artifactId>
<version>1.0.2</version>
</dependency>
在github上有如何使用的模板,复制过来修改即可
客户端
<?xml version="1.0" encoding="UTF-8"?>
<bean id="rmiClientSetting" abstract="true">
<!-- 是否启动时加载stub -->
<property name="refreshEndpointsOnStartup" value="false" />
<!-- 调用异常时,将重新加载stub -->
<property name="refreshEndpointsOnConnectFailure" value="true" />
<!-- 调用失败时是否切换到其他服务端 -->
<property name="switchEndpointOnFailure" value="true" />
<!-- 追踪拦截器启用 -->
<property name="registerTraceInterceptor" value="true" />
<!-- 缓存stub 继承AbstractRmiShortFormProxyFactoryBean才有-->
<property name="cacheEndpoints" value="true" />
</bean>
<!--数据库操作RMI-->
<bean id="studentService"
class="org.softamis.cluster4spring.rmi.RmiUrlListProxyFactoryBean" parent="rmiClientSetting">
<!-- 远程服务对象接口类 -->
<property name="serviceInterface" value="com.ksy.service.StudentService"/>
<!-- 远程对象地址list ,如果第一个无法使用,会抛异常,然后使用第二个去调用远程对象方法返回结果-->
<property name="serviceURLs" >
<list>
</list>
</property>
<!-- 调用时选择那个url的策略 -->
<property name="endpointSelectionPolicy">
<bean class="org.softamis.cluster4spring.support.invocation.ShuffleEndpointSelectionPolicy"/>
</property>
</bean>
<!--数据库操作RMI-->
<bean id="professionService"
class="org.softamis.cluster4spring.rmi.RmiUrlListProxyFactoryBean" parent="rmiClientSetting">
<!-- 远程服务对象接口类 -->
<property name="serviceInterface" value="com.ksy.service.ProfessionService"/>
<!-- 远程对象地址list ,如果第一个无法使用,会抛异常,然后使用第二个去调用远程对象方法返回结果-->
<property name="serviceURLs">
<list>
</list>
</property>
<!-- 调用时选择那个url的策略 -->
<property name="endpointSelectionPolicy">
<bean class="org.softamis.cluster4spring.support.invocation.ShuffleEndpointSelectionPolicy"/>
</property>
</bean>
<!--数据库操作RMI-->
<bean id="userService"
class="org.softamis.cluster4spring.rmi.RmiUrlListProxyFactoryBean" parent="rmiClientSetting">
<!-- 远程服务对象接口类 -->
<property name="serviceInterface" value="com.ksy.service.UserService"/>
<!-- 远程对象地址list ,如果第一个无法使用,会抛异常,然后使用第二个去调用远程对象方法返回结果-->
<property name="serviceURLs">
<list>
</list>
</property>
<!-- 调用时选择那个url的策略 -->
<property name="endpointSelectionPolicy">
<bean class="org.softamis.cluster4spring.support.invocation.ShuffleEndpointSelectionPolicy"/>
</property>
</bean>
</beans>
服务端
<?xml version="1.0" encoding="UTF-8"?>
<context:component-scan base-package="com.ksy.service.serviceImpl"/>
<!-- 将一个类发布为一个RMI服务 使用RmiServiceExporter暴露服务-->
<!--学生 服务类-->
<bean id="studentService" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- 设置服务名称 -->
<property name="serviceName" value="studentService"/>
<!-- 设置服务类 -->
<property name="service" ref="studentServiceImpl"/>
<!-- 设置服务接口 -->
<property name="serviceInterface" value="com.ksy.service.StudentService"/>
<!-- 注册端口号 用来暴露发现服务 -->
<property name="registryPort" value="8803"/>
<!-- 设置服务端口号 用来传输数据 这个参数是可选参数, 当不设置的时候, 数据传输会使用随机端口号 -->
<!--<property name="servicePort" value="7788"/>-->
</bean>
<!--用户 服务类-->
<bean id="userService" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- 设置服务名称 -->
<property name="serviceName" value="studentService"/>
<!-- 设置服务类 -->
<property name="service" ref="userServiceImpl"/>
<!-- 设置服务接口 -->
<property name="serviceInterface" value="com.ksy.service.UserService"/>
<!-- 注册端口号 用来暴露发现服务 -->
<property name="registryPort" value="8803"/>
<!-- 设置服务端口号 用来传输数据 这个参数是可选参数, 当不设置的时候, 数据传输会使用随机端口号 -->
<!--<property name="servicePort" value="7788"/>-->
</bean>
<!--用户 服务类-->
<bean id="professionService" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- 设置服务名称 -->
<property name="serviceName" value="professionService"/>
<!-- 设置服务类 -->
<property name="service" ref="professionServiceImpl"/>
<!-- 设置服务接口 -->
<property name="serviceInterface" value="com.ksy.service.ProfessionService"/>
<!-- 注册端口号 用来暴露发现服务 -->
<property name="registryPort" value="8803"/>
<!-- 设置服务端口号 用来传输数据 这个参数是可选参数, 当不设置的时候, 数据传输会使用随机端口号 -->
<!--<property name="servicePort" value="7788"/>-->
</bean>
</beans>
最后要在application中导入cluster4spring
<import resource="cluster4spring.xml"/>
启动两个服务端程序
可以正常运行
在后台看到启动的是服务1
关掉服务1
再次运行
服务2也正常启动
3.在服务器上部署服务端
服务端打包的时候要把war修改为jar
然后加入插件
需要在jar包里面删掉*.SF,*.DSA,*.RSA文件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.ksy.service.Enter</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
然后把客户端也打包到服务器,能够成功运行
二、遇到的问题

三、收获

servlet,RMI,webservice之间的区

servlet:提供了请求/响应模式,是JAVA的一种规范,只能使用于java上,用来替代早期使用的难懂的CGI,是一种无状态的请求响应,客户端访问一个服务器的url,只需要发送简单的httprequest即可。 规定了四个范围:pageContext、request、session、application。一定依赖于各种SERVLET容器,但servlet只能接受一个简单的http请求;   
  WebService最早是微软提出了一种以XML为载体网络信息传输的规范,现在几乎所有的语言与平台都支持,带有状态机制,不依赖于SERVLET容器,可以发送一个xml作为其请求内容,WebService通常是基于http的远程方法调用(RMI),号称是可以反回远程对象, 一般来说客户段可以象调用本地方法一样调用WebService的方法。  

  传输:   
  servlet使用http协议传输数据,如果你用Servlet返回XML,那个XML的描述框架就是你定的,必须告知使用者具体的说明,没有统一标准。   
  webservice使用固定的XML格式封装成soap消息,可以使用http作为底层数据传输,但并不局限于http协议,方法返回消息是有标准的。   
    
  返回结果:   
  servlet返回的是html页面;   
  webservice返回的可以是复杂对象甚至使用附件或者mutidata的二进制文件。   
    
  部署:   
  servlet需要遵守j2ee的Web   Application规范部署的应用服务器上,如tomcat,weblogic,websphere;   
  WebService则需要有WSDL文件来部署服务,或者使用UDDI注册。   
    
  优势:   
  WebService的跨平台特性是servlet不能比的,可以被各种语言调用;   
  servlet相对来说速度上的优势也是不可忽视的。

  

 

  接下来在看看RMI和webservice中的
 
  rmi的客户端和服务端都必须是java,webservice没有这个限制
  webservice是在http协议上传递xml文本文件,与语言和平台无关
  rmi是在tcp协议上传递可序列化的java对象,只能用在java虚拟机上,绑定语言
  RMI是EJB远程调用的基础,仅用RMI技术就可以实现远程调用,使用EJB是为了实现组件,事物,资源池,集群等功能。
  WebService是通过XML来传输数据,可用http等协议因此可在异构系统间传递,并且可以穿过防火墙,可在公网上远程调用



四、明天的计划
完成最后的部署两台WEB,通过Nginx配置两台WEB随机访问,两台WEB可以随机访问两台Service



返回列表 返回列表
评论

    分享到