发表于: 2017-11-22 23:02:12

2 677


今天完成的事

服务器上实现远程调用

首先把两台service部署到服务器上

因为两台service中有main方法,所以普通的打jar包的方法是行不通的,要在pom中添加插件,并指定main方法的位置

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <!-- Servlet版本对应 -->
   <version>3.1</version>
   <configuration>
       <source>1.8</source>
       <target>1.8</target>
       <encoding>UTF-8</encoding>
   </configuration>
</plugin>

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>1.4</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.ManifestResourceTransformer">
                       <mainClass>com.task8.jnshu.server.RmiServer</mainClass>
                   </transformer>
                   <transformer
                           implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                       <resource>META-INF/spring.handlers</resource>
                   </transformer>
                   <transformer
                           implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                       <resource>META-INF/spring.schemas</resource>
                   </transformer>
               </transformers>
           </configuration>
       </execution>
   </executions>

</plugin>

上面标红的地方需要改成自己项目中对应的,至于其他的配置文件,只要遵守maven目录构造放进src/main/resourse,就不要另外的配置,约定优于配置

打出jar之后可以直接上传到服务器,使用java -jar xxx.jar就可以运行main方法

为了保持service的运行,我们要想办法锁住 这个程序,让其不停止

两种方法,亲测可用


接着部署另一台service,需要注意的是两台service应该使serviceName和registryPort不相同,否则会发生报错或者冲突


在服务器上启动过service之后肯能会遇到一个问题:

需要去做其他的事,但是这个xshell窗口因为运行了main方法,所以不能进行其他操作

这里就要使用   java -jar xxx.jar & 让这个命令可以使用ctrl+z 挂载到后台,以进行其他操作


之后可能有人要问,如果我需要把xshell关了也能是service运行呢? 

那么我们就先来看一下为什么关闭xshell就会导致service停止:

如上方到后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。如果我们要在退出shell的时候继续运行进程,则需要使用nohup忽略hangup信号,或者setsid将将父进程设为init进程(进程号为1)

知道为什么了就直接使用 nohup java  -jar xxx,jar & 或者 setsid  java -jar xxxx.jar  &  命令来保证关了shell不会使service停止


PS:以上命令也可用于其他命令


之后部署web,需要注意的是任务要求中可以随机访问两台service,所以就需要有专门的类来选择使用哪台service,以及其中一台service挂掉自动使用另一台service   这里借(chao)鉴(xi)了于博滔的日报中的代码  

public static StudentService getS() {
StudentService studentService;
   Random random = new Random();
   Integer num = random.nextInt(2)+1;
   if(num == 1){
logger.info("============>进入Service0");
       try {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
           studentService = (StudentService) context.getBean("StudentService0");
       }catch (Exception e){
logger.info("============>Service0挂了,用1");
           logger.error("错误信息:"+e.getMessage());
           ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
           studentService = (StudentService) context.getBean("StudentService1");
           e.printStackTrace();
       }
}else{
logger.info("============>进入Service1");
       try {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
           studentService = (StudentService) context.getBean("StudentService1");
       }catch (Exception e){
logger.error("错误信息:"+e.getMessage());
           logger.info("============>Service1挂了,用0");
           ApplicationContext context = new ClassPathXmlApplicationContext("spring-mybatis.xml");
           studentService = (StudentService) context.getBean("StudentService0");
           e.printStackTrace();
       }
}
return studentService;
}

在controller中使用

private StudentService studentService (){
return RandomServiceUtil.getS();
}

来调用该类

使用studentService()调用类中的方法

studentService().allStudent()


之后容器运行web

测试接口,并查看日志

关掉其中一台service,查看日志

好的,达成任务要求

接下来关闭一台web

这里需要查看Nginx日志

两台都工作的情况


关掉一台WEB的情况


好的  任务结束


深度思考:

什么是rmi?为什么要使用rmi框架?
RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个项目(或者是jvm)上的对象调用另一个项目中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口调用,使用RMI可以更好的完成分布式,提高项目的稳定性
什么是SCA?
SCA全称Service Component Architecture,即服务组件框架。它由BEA、IBM、Oracle等知名中间件厂商联合制定的一套符合SOA思想的规范。
服务组件框架(SCA)提供了一套可构建基于面向服务的应用系统的编程模型。它的核心概念是服务及其相关实现。服务由接口定义,而接口包含一组操作。服务实现可以引用其他服务,称为引用。服务可以有一个或多个属性,这些属性是可以在外部配置的数据值。
  SCA中的一个关键推动因素是Service Data Object(服务数据对象,SDO)。
  SCA组件被组成为程序集。程序集是服务级的应用程序,它是服务的集合,这些服务被连接在一起,并进行了正确的配置。SCA程序集运行在两个级别:第一种情况,程序集是系统内的一组松散连接的组件;另一种情况,程序集是模块内的一组松散连接的组件。二者的区别在于,一般来说,模块是组件的集合,而系统是模块的集合。此外,系统对应于“大规模编程”(programming in the large或megaprogramming),而模块对应于“小规模编程”(programming in the small)
  将组件连接到它所依赖的服务的方式就是服务网络“装配”的方式。程序集已经在许多技术和框架中广为应用,比如CORBA、J2EE、ATG Dynamo和Spring,也就是说,它并不是新出现的。从这些技术中我们可以知道,程序集提供了许多重要的优点,比如更轻松的迭代开发,以及避免使业务逻辑依赖于中间件容器。SCA使用程序集解决了许多SOA开发中的重要问题,包括:
  业务逻辑与底层基础架构、服务质量和传输的分离。
  “小规模编程”与“大规模编程”的联系。
  为架构的设计、编码和操作性部署在自底向上(bottom-up)和自顶向下(top-down)两种方法中来回切换提供了一种统一的方式。
什么是分布式?分布式有什么优点?
就是同一个服务,把数据库的不同部分分开建立到不同的服务器上。以缓解数据库大量数据访问的压力。
很多大公司的业务量比较大,每天的访问量都达到几百万上千万,甚至上亿的访问量,在访问量不是很大的情况下,是可以通过提高单台服务器的配置来满足需求的。但是当单台服务器已经满足不了需求的时候就需要做分布式处理了。毕竟一台服务器的处理能力是有限的。
如果分散到几台甚至几十台几百天电脑上,其优势就显现出来了
为什么要把web和service分离?应用了哪些概念?
我们将web和service分离,就是为了实现分布式,部署多台service是为了在有一台挂掉之后服务器仍可以正常运行,而不是导致整个项目崩溃,其实是用改应用了远程调用,以及集群的概念(这里我不太清楚,瞎说的)



遇到的问题:

【问题】部署两台Service只能访问一台
【日期】2017.11.22
【原因】两台serviceName一样,controller中的bean名称多加了个空格
【怎么发现的】有一台不输出日志
【修复】更改Name   去掉空格
【在哪些文件修改了】rmi-server.xml   controller
【我导致的】是
【解决bug的时间】2h
【教训】别特码乱碰空格


明天的计划:

开始任务9

拆分禅道



收获:对RMI的使用和理解更深了


任务进度:任务8已完成

任务开始时间:2017.11.18

延期风险:已延期两天





返回列表 返回列表
评论

    分享到