`
mozhenghua
  • 浏览: 324448 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于Maven部署的分布式服务介绍

 
阅读更多

1.背景

Lina解决了目前Jar包调用下的问题(启动慢、耦合度高、依赖传递、内存消耗大等问题) ,将原来在一个虚拟机中运行的程序,分散到了多个不同的虚拟机中运行,将原来的系统改造成了一个分布式服务系统。
一期在线上有点评这一个服务使用Lina来发布服务。Lina详细说明请参照(http://wiki.koubei.com/index.php/Rd/HuoNiao/Lina )。
在使用了之后我觉得lina有如下优点:

  1. 使用通透的方式将rmi协议封装了,通过使用spring的factroybean客户端只需要关心服务器端所调用的接口和服务的暴露的服务名称,就能调用了服务了。
  2. 使用了monitor模块,使用aop方式嫁接到原有系统中,在系统运行的时候可以直观即时地查看到系统的负载状况。
另外,本文中提到的的相关代码,如果您想查看源代码的话可以发邮件来向我索取 baisui@taobao.com

2.问题

体验了这些优点之后仍然觉得有以下不足,觉得还有改善的空间。

2.1.为每个服务对象要配置一个export代理工厂

每一个向外暴露的服务都需要配置这样一个RmiServiceExporter的代理对象,这样IOC容器中的对象就会在RmiServiceExporter的帮助下将服务以rmi的协议公布出去,是的,这样是正确的。但是,当将来某一天由于处于性能的考虑需要将服务以其他的方式向外公开,比如,使用hession协议,或者说同一个服务需要同时以hession和rmi两种协议向外公开服务,那么,如果使用现有的方式部署的话需要怎样修改呢?很明显,原有的大量的配置都需要修改。

2.2.简化客户端调用分布式服务方式

现在在客户端调用lina分布式服务,需要在spring中配置一个服务端代理对象,下面是一个例子

客户端的配置也同样存在潜在的风险:

  1. 需要为每一个服务,配置相应的客户端配置,这样一来,客户端的配置量也挺大的,如果同一个服务在n个地方有调用的话就需要配置n份
  2. 如果某一天服务端的服务的配置信息有所改动的话,那么就要查找所有客户端的配置,将它们一一修改掉,可想而知这是一项非常繁琐而且容易出错的工作

2.3 每个服务对客户端是一个独立的服务名,这样服务端维护监控存在潜在风险。

可以将服务的通讯方式改造成另外中形式:

3.完善

3.1.问题总结:

  1. 要为每个服务端服务,调用端配置一个spring配置文件。这样日后维护会比较麻烦。发布流程会比较繁琐,且容易出错。
  2. 服务器端和客户端是单独传输没有统一的网关。

3.2.改善的思路:

  1. 服务器端bean的配置问题:对于解决这些问题,可以利用maven强大的插件功能,让maven来自动生成这些配置服务器端的配置文件,在发布服务器端的jar包的时候,可以自动生成服务器端bean的代理文件,并且,在打包的时候可以自动将之前生成的配置文件一同打到jar包,这个过程中用户只需要简单的敲一些maven的命令。
  2. 客户端xml配置问题:客户端要为每个服务调用都配置一个配置文件,是因为客户端调用的时候并不知道它能调用的服务在哪儿,在哪个服务器上,ip是多少,端口是多少,服务名是什么,所以这些都必须事先就在调用端设置好,这样客户端在启动之后才能通过客户端的配置正常加载服务器端的配置。所以,可以增加一个服务中心的服务,在服务端启动的时候,将服务所在的ip地址,服务名称,服务端口发布到服务中心的数据库中。
  3. 客户端所要依赖的开发包仅仅就是服务端部署包的中jar包中的那些服务接口和服务接口所依赖的pojo对象,可以开发一个maven的plugin在maven运行的package阶段为服务器端生成一个客户端依赖包。这样在客户端部署的时候只需要调用这个客户端包就行了。改造成这样的通讯方式之后客户端和服务器端的通讯就可以通过统一的gateway来通讯了,在原来的通讯方式下monitor模块是通过aop的方式嫁接到原有系统中的,现有的架构中 monitor模块可以不通过AOP方式配置,这样系统的运行效率就会提高。

3.3.客户端调用方式改善

对于客户端来说,action所依赖的service对象只需要通过ServiceLookup类的findService()方法就能找到,并不需要关心服务所在的服务器ip地址端口等信息。

以下是改造之后的客户端查找服务器端调用的时序图:

如上图,webwork查找服务端服务的主要流程如下:

  1. Webwork调用ActionInvocation的invoke函数,按照拦截器配置的顺序调用DistributeServiceInjectInterceptor拦截器(这个拦截器的作用是为目标action注入分布式服务的)
  2. DistributeServiceInjectInterceptor利用反射的机制查找MyAction的分布式服务的注入点。

在需要注入分布式服务的javabean的set方法上打上一个@Inject标识,这样DistributeServiceInjectInterceptor就会发现这个action有分布式服务的使用需求,之后它就会调用LookupService的findService方法找到需要的服务对象,并且将这个服务对象注入到action中。

3.4.LookupService

以下是和LookupService这个类相关类的类图:

当ServiceLookup初始化时会使用JGroups的JChannel对象在JGroups的group中将ServiceLookup注册为Group中的一个成员,当ServiceLookup的生命周期中会实时监听分布式服务中的事件。比如,当分布式Group中增加了一个新的服务节点,或者,某个服务节点下线了。这样的变动需要自动更新各个服务调用端的ServiceLookup对象中缓存的服务信息(服务所在ip、端口、服务名)。JGroup承担了分布式系统中消息分发的功能。

3.5.网络结构图

如上图所示,系统一共有三个部分,第一部分是服务提供服务器,第二部分保存服务元数据信息的数据库服务器,第三部分是调用服务的调用端。

以下是服务发布到服务调用端调用服务这个流程的说明:

  1. 分布式服务系统集群中有一台服务器有一些新的服务需要上线,首先服务器会初始化本虚拟机中的对象。
  2. 将自己服务器中的服务,服务所在的ip地址占用的端口发布到服务中心的数据库中。
  3. 在本虚拟机中初始化一个jChannel对象加入到分布式服务的JGroup中,并且向Group中广播一个更新服务员数据信息的消息。
  4. 各个客户端调用者收到集群中的发过来的更新消息,将本机中原有信息删除。
  5. 客户端调用者重新到服务中心中加载新的服务元数据信息。

3.6.创建服务对象

基于以上的考虑,我们需要对现有分包的代码做一些小小的改动。需要做以下改动适应新的分布式服务改造:

在开发过程中,需要标识要往外部发布服务的接口。例如在开发【免费网店房源关联】接口过程中需要用com.koubei.lina.ext.Service的annotation标识服务接口,如下所示:在服务接口上用@Service标记,后期初始化启动过程中就会自动将这个接口绑定到预先设置好的端口上向外发布。示例代码如下:

通过在IDianAssociationService 服务接口上标识@Service之后,有以下作用:

  1. 初始化Spring的需要

    虚拟机在初始化的时候就知道这个实现这个接口的服务对象需要以rmi协议(或者其他服务)的形式向外发布服务。系统就可以自动为其生成export代理对象而不需要手动去配置了。

  2. 生成客户端包

    当用maven的插件生成客户端依赖包的时候,maven插件会遍历已经服务器端包中的所有资源,当发现某个接口上标识了@Service的标识之后,插件会将这个接口的class文件抽取出来,同时也会分析Service所依赖的pojo对象,如果这个pojo类资源文件也存在本服务器包中的话,那么也一并会抽取出来,将这些抽取出来的资源文件重新打包在一个新的client jar包中。供客户端调用者调用。

3.7.客户端使用分布式服务

3.7.1.配置客户端包的依赖

在客户开发工程中需要在maven的pom.xml文件中添加服务器端客户端jar(该jar中只包含了服务service接口,和接口依赖的pojo对象)的依赖。配置如下:

注意,以上的dependency节点需要额外加一个classifier属性,值必须为client,这样项目在编译的时候就会从maven库中取到服务包的client包了。

3.7.2.编写action

在Webwork中如果需要调用到分布式服务中的某个服务对象,很简单只需要像下面这样的改动:

3.7.3.添加拦截器配置

为了要让webwork能够识别这个@Inject标记,需要在webwork中添加一个拦截器。

需要让distributeServiceInject这个拦截器添加到HomeAction的默认拦截器栈中,才能让distributeServiceInject在调用action的时候起作用。

3.8.Maven插件介绍

3.8.1.ServiceClassManager

com.koubei.plugin.distribute.ServiceGatewayBuild 插件的作用是在maven的compile阶段,可以在classoutput文件夹中自动生成lina service代理文件。文件内容如下:

以上配置文件中的端口号,和原目标配置文件需要在pom.xml的plugin的配置节点中配置:

3.8.2.PackageClientJarPlugin

将ServiceGatewayBuild插件生成的客户端依赖的class文件打包成clientjar包。

3.8.3.ServiceGatewayBuild

自动抽取服务端客户端依赖的class文件。

3.8.4.自定义plugin与maven生命周期绑定

3.8.5.发布服务

以口碑店分包项目(http://10.5.58.201/svn/Koubei/branches/Branch_galaxy_091014/koubei-dian )为例,在项目工程的pom.xml文件中配置自定义plugin:

将以上提到的三个插件绑定到maven执行时的生命周期中。

以上都配置好之后就可以在koubei-dian项目下执行maven命令了:

执行

mvn package

命令就会在项目target目录下面生成两个jar包,一个koubei-dian的服务端jar包文件(koubei-dian-1.0.0.jar),另外一个是客户端依赖的jar包文件(koubei-dian-1.0.0-client.jar)。

执行

mvn deploy

就会将生成的两个jar包自动部署到maven的本地仓库中去。可以发现,如果一旦为koubei-dian项目设置好了插件的话,生成jar的工作就归结到执行mvn的命令了,多么的简单呀。这里我们不得不赞叹maven的功能是在太强大了,它已经将项目发布的生命周期的各个环节建模,并且,可以让用户自定义各个生命周期执行的任务。这样一来对于项目发布,构建带来了优美,和方便。

3.8.6.启动服务

在命令行中执行以下命令:

java -DserviceModule=koubei-dian ^
-classpath ./target/koubei-dian-1.0.0.jar;^
D:/j2ee_solution/eclipse/workspace/Lina/dist/lina.server.jar;^
D:/j2ee_solution/eclipse/workspace/Lina/target/memcached-2.0.1.jar;^
D:/mvn_test/lina-ext/target/lina-ext-1.0-SNAPSHOT.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/log4j-1.2.12.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/commons-logging-1.0.4.jar;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/spring.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/commons-dbcp.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/commons-collections.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/commons-pool.jar;^
D:/j2ee_solution/wokspace/Release20080225/dist/koubei-core.jar;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/taobao-cache.jar;^
D:/j2ee_solution/wokspace/Release20080225/dist/koubei-util.jar;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/ibatis-2.3.0.677.jar;^
D:/j2ee_solution/wokspace/Release20080225/dist/koubei-cache.jar;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/oscache-2.3.2.jar;^
D:/j2ee_solution/eclipse/workspace/koubei-dian_bak/jars/commons-beanutils.jar;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/commons-lang.jar;^
./config;^
D:/j2ee_solution/wokspace/Release20080225/WebContent/WEB-INF/lib/mysql-connector-java-5.1.5-bin.jar ^
com.koubei.lina.ext.ModuleLauncher

执行了这个命令之后服务就启动了。

3.8.7.服务监控页面

当服务服务器启动,向元数据服务器中注册服务信息之后,就可以对外发布服务了。这时可以打开本地web页面查看本地局域网中的服务对象来核实是否有需要的服务对象存在。比如,打开页面:http://localhost/monitor/ 可以看到本局域网中所有服务对象的信息:

从该监控台上可以查看到以下信息:

  1. 服务模块所在的服务器名称
  2. 服务的名称,该属性的作用是,当spring启动的时候初始化作为初始化参数用的
  3. 服务所在的端口
  4. 服务所在ip地址

服务发布时间戳,该时间戳是校验客户端代码版本与服务器端版本是否一致时用的,当服务器端的时间戳与客户端时间戳比较,相等则说明版本一致。

4.有待完善的东西

4.1.使用OSGI来改造现有服务构架

在3.8.6启动服务中大家可以看到启动服务的命令相当长,可以发现在服务启动的命令中,classpath中除了koubei-dian-1.0.0.jar这个jar包之外其他依赖的jar包都是系统级的jar包,如果启动多个服务的话,势必需要在虚拟机之中重复加载系统级的jar包,这样对服务器的内存是一种浪费。

另外服务所依赖的一些公共bean,例如datasource对象,对于多个服务来说是可以共用的,如果,能在服务器上只保存一份dadasource对象的话,对于服用对象,节约服务器内存,日后更新datasource配置来说都大有好处。

以上这些问题,可以使用OSGI(公用服务网关)来解决。在之后的文档中,将介绍如何使用OSGI来优化现有系统的构造。

4.2.消息中心

在现有系统中,同步各个服务引用端对象的信息是用过JGroup组件来同步的,虽然我在本机测试环境下测试性能还可以,但是还没有经过系统级的大并发量的测试。那天听说老常同志在开发异步消息系统,据说这个消息系统会是一个高可靠的系统,我想到时候说不定能用这个异步消息系统来替换现有jgroup的状态同步问题。

4.3.服务中心监控

现在的监控中心中只能看出有什么服务可以调用,后期改造可以在监控中心中可以增加服务负载量的监控等。

5.引用

  1. Maven class加载机制 http://maven.apache.org/guides/mini/guide-maven-classloading.html
  2. Maven plugin 开发方式 http://maven.apache.org/plugin-developers/index.html
  3. Jgroups介绍 http://www.jgroups.org/
  4. java annotations说明 http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
  5. 口碑lina说明文档 http://wiki.koubei.com/index.php/Rd/HuoNiao/Lina
分享到:
评论

相关推荐

    基于Dubbo的分布式系统架构实战.pdf

    根据提供的文档信息,我们可以归纳出以下几个关键的知识点: ### 一、使用Dubbo对传统工程进行服务化改造 #### 1.1 改造思路 ...这对于学习和实践基于Dubbo的分布式系统架构具有重要的指导意义。

    基于springcloud + vue的分布式服务paascloud项目部署文档.zip

    在本文中,我们将深入探讨如何部署一个基于SpringCloud和Vue.js的分布式服务系统,这个系统被称为"Paascloud"。Paascloud是一个典型的微服务架构平台,它利用SpringCloud的强大功能来实现服务治理,而Vue.js则作为...

    基于Maven构建的SPRING+MYBATIS+ZOOKEEPER+DUBBO的分布式系统.zip

    《基于Maven构建的SPRING+MYBATIS+ZOOKEEPER+DUBBO的分布式系统详解》 在现代企业级应用开发中,分布式系统已经成为主流。本项目以Maven为构建工具,融合了Spring、MyBatis、ZooKeeper和Dubbo等核心组件,构建了一...

    通过Shell脚本,结合Git实现增量部署基于Maven的Java项目.zip

    本文将详细探讨如何通过Shell脚本和Git实现基于Maven的Java项目的增量部署。 首先,让我们理解核心组件的作用: 1. **Git**:这是一个分布式版本控制系统,用于跟踪对代码库的修改。在增量部署过程中,Git帮助我们...

    springboot 基于maven的多模块工程

    总之,“springboot基于maven的多模块工程”展示了如何通过Spring Boot和Maven构建一个模块化、微服务化的系统,实现了消费者和服务提供者之间的交互,利用Spring Cloud组件来支持服务发现和调用。这样的架构设计...

    分布式架构项目介绍

    ### 分布式架构项目介绍 #### 一、主要技术概览 在本分布式系统项目中,我们使用了一系列关键技术和框架来构建一个灵活、可扩展且高性能的架构。这些技术包括但不限于Spring、Spring MVC、MyBatis、Git、Maven、...

    Dubbo分布式服务管理

    5. 启动服务:通过Maven命令打包部署,启动服务提供者和消费者。 总结来说,Dubbo分布式服务管理是构建大规模分布式系统的基石,通过Maven项目管理和Dubbo的组件机制,可以有效地实现服务的发布、消费、监控,提升...

    maven springboot jta mybatis 分布式事物

    在本项目中,"maven springboot jta mybatis 分布式事物" 是一个核心主题,这涉及到几个关键技术和概念,下面将详细解释这些知识点。 首先,`Maven` 是一个构建工具,它帮助开发者管理项目的依赖关系,构建流程以及...

    基于SpringMVC+Spring+HBase+Maven搭建的Hadoop分布式云盘系统.zip

    这是一个基于Java技术栈,利用SpringMVC、Spring、HBase和Maven构建的Hadoop分布式云盘系统的项目。该项目旨在实现一个高效的、可扩展的云存储解决方案,利用Hadoop的分布式特性来处理大规模数据存储需求。 首先,...

    基于Maven、Dubbo、Zookeeper、Spring和父子工程之间调用的新手项目搭建

    本文将详细介绍如何基于Maven、Dubbo、Zookeeper以及Spring框架搭建一个新手友好的父子工程调用项目。 首先,Maven是Java开发中的项目管理工具,它通过引入依赖管理和项目生命周期的概念,使得项目的构建和维护变得...

    Spring+ActiveMQ实现,基于Maven

    本项目基于Maven构建,提供了对Topic的实现,同时也支持轻松切换到Queue模式。 **Spring框架** Spring是一个开源的Java平台,它为构建企业级应用提供了一个全面的编程和配置模型。Spring的核心特性包括依赖注入...

    基于Maven的ActiveMQ的简单实例

    在创建基于Maven的ActiveMQ实例时,我们需要在pom.xml中添加ActiveMQ相关的依赖。首先,确保你的Maven环境已经正确安装并配置。然后,在pom.xml文件中添加以下依赖: ```xml <groupId>org.apache.activemq ...

    ssm+maven+dubbo+zookeeper分布式架构

    Dubbo的核心是基于RPC(远程过程调用)的通信机制,使得服务提供者可以在一个独立的应用中暴露服务,服务消费者可以透明地调用这些服务,降低了服务间的耦合度。 **4. Zookeeper** Zookeeper 是一个分布式的,开放...

    分布式微服务电商系统搭建

    最后,对于分布式微服务电商系统,持续集成和持续部署(CI/CD)也是重要的一环,这通常涉及到Jenkins、GitLab CI/CD等工具,以实现自动化构建、测试和部署,确保系统的快速迭代和稳定运行。此外,系统性能监控和日志...

    基于Hadoop的分布式系统依赖的所有JAR包

    本资源集合了Maven、HDFS、MapReduce等相关所有JAR包及依赖,为构建基于Hadoop的分布式系统提供了必要的库。 首先,我们来详细了解一下Hadoop的这些关键组件: 1. **HDFS**:Hadoop分布式文件系统是Hadoop的核心,...

    dubbo-demo-maven版

    总结,"dubbo-demo-maven版"项目为我们提供了一个完整的、基于Maven构建的Dubbo示例,涵盖了Dubbo的核心功能,包括服务提供、消费、注册、协议、监控等。通过这个项目,开发者可以快速上手Dubbo,理解分布式服务的...

    基于maven的SpringCloud初始项目

    ### 基于Maven的Spring Cloud初始项目详解 #### 一、项目介绍 本项目是基于Maven构建工具创建的Spring Cloud基础框架项目。它主要用于快速搭建Spring Cloud微服务应用,减少开发前期的准备工作时间。该初始项目...

    eureka分布式微服务

    根据给定的文件信息,我们将详细介绍如何创建一个名为`particle-common-eureka`的服务发现中心,并基于Maven项目进行构建。 ### 三、Maven项目搭建 首先,我们需要创建一个名为`particle-common-eureka`的Maven...

    它是基于Dubbo的分布式系统架构,快速简单的上手,有服务层、前端页面层、定时任务系统、日志系统等.zip

    标题中的“基于Dubbo的分布式系统架构”是指利用Apache Dubbo这一高性能的Java RPC框架来构建的分布式应用程序。Dubbo可以使得服务提供者和服务消费者在分布式环境中相互通信,提高系统的可扩展性和容错性。它支持...

    10 - 基于Maven-SpringBoot-Dubbo微服务实战

    **标题:“10 - 基于Maven-SpringBoot-Dubbo微服务实战”** 本文将深入探讨如何构建一个基于Maven、SpringBoot和Dubbo的微服务实战项目。Maven是Java开发中的一个项目管理和依赖管理工具,SpringBoot简化了Spring...

Global site tag (gtag.js) - Google Analytics