关于分布式服务架构的背景和需求可查阅http://dubbo.io/。不同于传统的单工程项目,本文主要学习如何通过maven和dubbo将构建分布项目以及服务模块,下面直接开始。

创建项目以及模块

创建Maven Project —— mcweb,这个是所有模块的父模块,packaging类型为pom

创建Maven Module —— mcweb-api,这个模块是服务接口层,packaging类型为jar

创建Maven Module —— mcweb-logic,这个是服务实现层或者服务提供者,packaging类型为jar

创建Maven Module —— mcweb-web,这个是web层或者服务消费者,packaging类型为war

 

 

 

如果你还不是很清楚多模块应用的创建过程,可参考这篇文章

http://www.cnblogs.com/quanyongan/archive/2013/05/28/3103243.html

我们将以这个简单的样例工程开启分布式开发学习之旅。

配置模块依赖关系

mcweb-service依赖mcweb-api

/mcweb-service/pom.xml

 

<dependencies>

<dependency>

  <groupId>com.edu.mcweb.api</groupId>

  <artifactId>mcweb-api</artifactId>

  <version>0.0.1-SNAPSHOT</version>

</dependency>

</dependencies>

 

mcweb-web 依赖mcweb-api

/mcweb-web/pom.xml

<dependencies>

<dependency>

   <groupId>com.edu.mcweb.api</groupId>

   <artifactId>mcweb-api</artifactId>

   <version>0.0.1-SNAPSHOT</version>

</dependency>

<dependency>

  <groupId>com.edu.mcweb.service</groupId>

  <artifactId>mcweb-service</artifactId>

  <version>0.0.1-SNAPSHOT</version>

</dependency>

</dependencies>

 

模块配置与实现

mcweb-api

mcweb-api层是服务接口层,它的作用是向其他层暴露接口,不需要做其他配置,只需编写我们需要的接口即可,这是面向接口编程的很好例子。

 

\mcweb\mcweb-api\src\main\java\com\mcweb\api\dao\IUserDao.java

 

public interface IUserDao {

  public User query(Class<User> clazz,Object userId);

}

 

\mcweb\mcweb-api\src\main\java\com\mcweb\api\service\IUserService.java

 

public interface IUserService {

  public User query(String userId);

}

 

\mcweb\mcweb-api\src\main\java\com\mcweb\api\entity\User.java

 

public class User2 implements Serializable{

  private String id;

  private String userName;

  private String userChName;

  //省略getter,setter

}

mcweb-logic

模块配置

 

 

整个服务模块就是一个web工程,其配置和普通web工程一样,就多了一个dubbo-provider.xml,在applicationContext.xml引入即可(下面将介绍)。这些配置可以根据自己所采用的整合技术进行配置,在此略。

 

编写代码

\mcweb\mcweb-logic\src\main\java\com\mcweb\logic\dao\UserDao.java

 

@Repository

public class UserDao implements IUserDao {

  @PersistenceContext

  protected EntityManager em;

 

public User query(Class<User> clazz,Object userId) {

    //连接数据库的方式

    //return em.find(clazz, userId);

 

  User u = new User();

  u.setUserName("zhansan");

  u.setUserChName("张三");

  return u;

}

}

 

\mcweb\mcweb-logic\src\main\java\com\mcweb\logic\service\UserService.java

 

@Service

@Transactional

public class UserService implements IUserService {

  @Autowired

  private IUserDao userDao;

  public User query(String userId) {

     return userDao.query(User.class, userId);

}

}

 

部署启动测试

mcweb-logic也是web项目,可以先部署到tomcat运行看是否能正常启动。

mcweb-web

模块配置

 

 

同理,整个消费模块也是一个web工程,其配置和普通web工程一样,就多了一个dubbo-consumer.xml,在applicationContext.xml引入即可(下面将介绍)。这些配置可以根据自己所采用的整合技术进行配置,在此略。

编写代码

\mcweb\mcweb-web\src\main\java\com\mcweb\web\controller\UserController.java

 

@Controller

@RequestMapping(value="/user")

public class UserController {

  @Autowired

  private IUserService userService;

  @RequestMapping(value="/query",method = RequestMethod.GET)

  public String query(@RequestParam("userId") String userId,Model model) {

      User user = userService.query(userId);

      model.addAttribute("user", user);

      return "/user.jsp";

}

}

 

\mcweb\mcweb-web\src\main\webapp\WEB-INF\pages\user.jsp

 

<body>

${user.userName}

</body>

部署启动测试

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mcweb.api.service.IUserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

 

现在,mcweb-logic和mcweb-web已经配置完成,mcweb-logic能正常启动,mcweb-web依赖mcweb-logic中的IUserService服务,如何让mcweb-web能够引用mcweb-logic中的服务将是下面我们要学习的内容。

 

模块服务化

服务提供者和服务消费者是dubbo架构中两个主要角色,在上面的项目中,mcweb-logic就相当于服务提供者,mcweb-web相当于服务消费者。Dubbo 建议使用 Zookeeper 作为服务的注册中心,所以我们先安装Zookeeper。只要mcweb-logic向Zookeeper注册了服务之后,它就可以向mcweb-web提供依赖服务;同理,mcweb-web需要向Zookeeper申请需要引用mcweb-logic服务。

安装Zookeeper

配置服务提供者

引入相关jar

需要引入dubbo和zookeeper相关jar,\mcweb\pom.xml

 

<!-- dubbo start -->

<dependency>

   <groupId>com.alibaba</groupId>

   <artifactId>dubbo</artifactId>

   <version>2.5.3</version>

</dependency>

 

<dependency>

   <groupId>org.apache.zookeeper</groupId>

   <artifactId>zookeeper</artifactId>

   <version>3.4.9</version>

</dependency>

<dependency>

   <groupId>com.101tec</groupId>

   <artifactId>zkclient</artifactId>

   <version>0.7</version>

</dependency>

<dependency>

   <groupId>org.jboss.netty</groupId>

   <artifactId>netty</artifactId>

   <version>3.2.5.Final</version>

</dependency>

<!-- dubbo end -->

 

\mcweb\mcweb-logic\pom.xml

 

<dependency>

   <groupId>org.jboss.netty</groupId>

   <artifactId>netty</artifactId>

   <version>3.2.5.Final</version>

</dependency>

<dependency>

   <groupId>com.alibaba</groupId>

   <artifactId>dubbo</artifactId>

   <version>2.5.3</version>

   <exclusions>

   <exclusion>

   <groupId>org.springframework</groupId>

   <artifactId>spring</artifactId>

   </exclusion>

   </exclusions>

</dependency>

 

<dependency>

   <groupId>org.apache.zookeeper</groupId>

   <artifactId>zookeeper</artifactId>

   <version>3.4.9</version>

</dependency>

 

<dependency>

   <groupId>com.101tec</groupId>

   <artifactId>zkclient</artifactId>

    <version>0.7</version>

</dependency>

新建dubbo-provider.xml

\mcweb\mcweb-logic\src\main\resources\spring\dubbo-provider.xml

 

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans 

            http://www.springframework.org/schema/beans/spring-beans.xsd 

            http://code.alibabatech.com/schema/dubbo 

            http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

<!-- 提供方应用信息,用于计算依赖关系 -->

<dubbo:application name="mcweb-logic" />

 

<!-- zookeeper注册中心地址 -->

<dubbo:registry protocol="zookeeper" address="192.168.2.129:2181" />

 

<!-- 用dubbo协议在20880端口暴露服务 -->

<dubbo:protocol name="dubbo" port="20880" />

<!-- 服务接口 -->

<dubbo:service interface="com.mcweb.api.service.IUserService" ref="userService" />

 

</beans> 

 

在\mcweb\mcweb-logic\src\main\resources\spring\applicationContext.xml引入

dubbo-provider.xml

 

<?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" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" >

 

<!-- 注解驱动 -->

<context:annotation-config />

 

<!-- 包扫描 -->

<context:component-scan base-package="com.mcweb.logic" />

<import resource="dubbo-provider.xml" />  

</beans>

使用tomcat运行服务提供者

将mcweb-logic部署到tomcat中测试运行,可以看到tomcat控制台输出信息

 

11:14:06 [localhost-startStop-1-SendThread(192.168.2.129:2181)]

INFO <org.apache.zookeeper.ClientCnxn> Opening socket connection to server

192.168.2.129/192.168.2.129:2181.

Will not attempt to authenticate using SASL (unknown error)

11:14:06 [localhost-startStop-1-SendThread(192.168.2.129:2181)]

INFO <org.apache.zookeeper.ClientCnxn>

Socket connection established to 192.168.2.129/192.168.2.129:2181, initiating session

11:14:06 [localhost-startStop-1-SendThread(192.168.2.129:2181)]

INFO <org.apache.zookeeper.ClientCnxn>

Session establishment complete on server 192.168.2.129/192.168.2.129:2181, sessionid =

0x1572b87bcd30000, negotiated timeout = 30000

11:14:06 [localhost-startStop-1-EventThread]

INFO <org.I0Itec.zkclient.ZkClient> zookeeper state changed (SyncConnected)

 

而在zookeeper的后台日志信息中可以看到

 

[myid:] - INFO  [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@649]

- Got user-level KeeperException when processing sessionid:0x1572b87bcd30000

type:create cxid:0x6 zxid:0x7 txntype:-1 reqpath:n/a Error

Path:/dubbo/com.mcweb.api.service.IUserService Error:KeeperErrorCode =

NodeExists for /dubbo/com.mcweb.api.service.IUserService

 

可见,mcweb-logic的IUserService服务已经注册到了zookeeper中。

 

 

配置服务消费者

引入相关jar

mcweb\mcweb-web\pom.xml 和mcweb-logic引入的一样

新建dubbo-consumer.xml

\mcweb\mcweb-web\src\main\resources\spring\dubbo-consumer.xml

 

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans 

        http://www.springframework.org/schema/beans/spring-beans.xsd 

        http://code.alibabatech.com/schema/dubbo 

        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

<!-- 消费者应用名,不要与提供者一样 -->

<dubbo:application name="mcweb-web" />

 

<!-- 注册中心地址 -->

<dubbo:registry protocol="zookeeper" address="192.168.2.129:2181" />

<!-- 用户服务接口,check=false表示服务不启动消费者照样能启动 -->

<dubbo:reference interface="com.mcweb.api.service.IUserService" id="userService"

check="false" />

 

</beans> 

 

在\mcweb\mcweb-web\src\main\resources\spring\applicationContext.xml

中引入dubbo-consumer.xml

 

<?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" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" >

 

<!-- 注解驱动 -->

<context:annotation-config />

 

<!-- 包扫描 -->

<context:component-scan base-package="com.mcweb.web.controller" />

<import resource="dubbo-consumer.xml" />   

</beans>

使用tomcat运行服务消费者

再次将mcweb-web部署到tomcat中测试运行,可以看到tomcat控制台输出信息

 

INFO <org.apache.zookeeper.ClientCnxn>

Opening socket connection to server 192.168.2.129/192.168.2.129:2181.

Will not attempt to authenticate using SASL (unknown error)

INFO <org.apache.zookeeper.ClientCnxn>

Socket connection established to 192.168.2.129/192.168.2.129:2181, initiating session

INFO <org.apache.zookeeper.ClientCnxn>

Session establishment complete on server 192.168.2.129/192.168.2.129:2181,

sessionid = 0x1572b87bcd30001, negotiated timeout = 30000

INFO <org.I0Itec.zkclient.ZkClient> zookeeper state changed (SyncConnected)

 

可见mcweb-web能正常引用IUserService服务了。

 

部署测试

http://localhost:8090/mcweb-web/user/query.html?userId=aaaa

 

可见访问成功,至此,服务提供者和服务消费者已经配置成功。

 

dubbo管控台的安装

服务管理

dubbo 管控台可以对注册到 zookeeper 注册中心的服务或服务消费者进行管理,但 管控台是否正常对 Dubbo 服务没有影响。在dubbo的“首页 > 服务治理 > 服务”中可以看到已经注册到 zookeeper 注册中心的服务的相关情况。

 

 

 

小结

(1)通过maven构建分布式应用的基础模块并配置模块之间的依赖关系,大型的分布式应用通常根据业务需求划分很多模块,每一个模块就是一个工程。这样划分好处很多,比如,抽象出系统的基础服务模块,基础配置模块,基础服务模块,基础配置模为其他模块提供支撑;模块与模块之间独立开发测试,上线维护等等。可见,分布式架构给系统带来了很多灵活性。

(2)通过引入dubbo,将模块服务化。模块服务化通常将模块配置成服务提供者服务消费者,需要注意的是,服务提供者也可以作为服务消费者,因为服务提供者还有可能依赖于其他服务。记住下面这几个容易混淆服务化的标签

 

<!--将模块配置成服务提供者,通过ref属性将spring容器中的userService bean暴露成dubbo服务-->

<dubbo:service interface="com.mcweb.api.service.IUserService" ref="userService" />

<!--将模块配置成服务消费者,生成远程服务代理,通过id属性,可以和本地bean一样使用userService

可以check="false" 表示不检查服务是否启动-->

<dubbo:reference interface="com.mcweb.api.service.IUserService" id="userService"

check="false" />

<!--服务提供者缺省值配置-->

<dubbo:provider>

<!--服务消费者缺省值配置-->

<dubbo:consumer>

 

(3)zookeeper作为第三方服务协调中心,服务提供者向其注册服务,服务消费者向其申请引用服务。

(4)本文中采用tomcat容器运行dubbo服务,实际上运行与部署服务有多种方式,后面我们会进一步学习。

参考文档

http://dubbo.io/User+Guide-zh.htm

基于dubbo构建分布式项目与服务模块的更多相关文章

  1. 基于dubbo的分布式项目实例应用

    本文主要学习dubbo服务的启动检查.集群容错.服务均衡.线程模型.直连提供者.只定阅.只注册等知识点,希望通过实例演示进一步理解和掌握这些知识点. 启动检查 Dubbo缺省会在启动消费者时检查依赖的 ...

  2. 基于 dubbo 的分布式架构

    前言 现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的 SSM 项目来让第一次接触的同学能快速上手. 浅谈分布式架构 分布式架构单看这个名字 ...

  3. 基于Dubbo的分布式事务框架(LCN)

    原文地址:http://原文地址:https://github.com/1991wangliang/transaction 基于Dubbo的分布式事务框架(LCN) 该框架依赖Redis/dubbo/ ...

  4. Jenkins:基于linux构建ivy项目

    Jenkins:基于linux构建ivy项目 (二) 基于以上<Jenkins:VMware虚拟机Linux系统的详细安装和使用教程(一)>的配置再进行对ivy项目构建: 启动tomcat ...

  5. 滴滴出行基于RocketMQ构建企业级消息队列服务的实践

    小结: 1. https://mp.weixin.qq.com/s/v6NM3UgX-qTI7yO1QPCJrw 滴滴出行基于RocketMQ构建企业级消息队列服务的实践 原创: 江海挺 阿里巴巴中间 ...

  6. Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架

    Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloop import tornado.web from myhas ...

  7. 基于已构建S2SH项目配置全注解方式简化配置文件

    如果还不熟悉s2sh项目搭建的朋友可以先阅读 eclipse环境下基于tomcat-7.0.82构建struts2项目 eclipse环境下基于已构建struts2项目整合spring+hiberna ...

  8. Spring-boot:5分钟整合Dubbo构建分布式服务

    概述: Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常 ...

  9. eclipse环境下基于已构建struts2项目整合spring+hibernate

    本文是基于已构建的struts2项目基础上整合 spring+hibernate,若读者还不熟悉struts2项目,请先阅读 eclipse环境下基于tomcat-7.0.82构建struts2项目 ...

随机推荐

  1. [老文章搬家] [翻译] 深入解析win32 crt 调试堆

    09 年翻译的东西. 原文见:  http://www.nobugs.org/developer/win32/debug_crt_heap.html 在DeviceStudio的Debug编译模式下, ...

  2. C# XMLDocument

    今天开发一个WPF模块需要本地化保存一些用户设置,鉴于数据量不大,用XML. (要是再小的话可以用Resources 和 Settings). 清晰简短教程移步:http://bdk82924.ite ...

  3. maven配置远程仓库

    1,当中央仓库无法满足要求时,可能项目需要的构件存在另一个远程仓库中.可以在POM文件中配置该仓库.代码如下: <project> ...... <repositories> ...

  4. 完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法

    完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法   HTML5的语义化标签以及属性,可以让开发者非常方便地实现清晰的web页面布局,加上CSS3的效果渲染,快速建立丰富灵活的web页 ...

  5. AFNetworking 与 gbk 编码格式后台数据的使用

    仅针,后台数据为GBK编码时的AFNetWorking 使用情况: 1. Request failed: unacceptable content-type: text/html     soluti ...

  6. Archlinux安装MySQL5.7.14压缩包版

    现在Arch官方源里是MariaDB,MySQL扔到AUR里去了...感觉还是自己安装好些... (参考资料:度娘.官方文档) 贴配置: lts版的 在Vbox虚拟机测试 按照官方文档的安装步骤: 创 ...

  7. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  8. ProgressBar---进度条

    最近在处理标题进度条时,耗费了一些时间,现在总结一下ProgressBar的相关知识,有不对的地方请大神们批评指正! 进度条主要有以下三种: 1.对话框进度条 2.标题进度条 注意:requestWi ...

  9. Python全栈开发【基础四】

    Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...

  10. zabbix安装配置界面点击next step没反应

    修改/var/lib/php/session/宿主或者添加777权限 看到有个人说这个不能用,一开始我也没用,找了各种方式都不行,最后死马当作活马医,改了下权限,卧槽,一下子就OK了,日