项目要基于SOA架构
SOA架构:表现层和服务层是不同的工程。一个表现层可以去调用多个服务层,例如一个后台的表现层,能调用商品服务,用户服务,索引服务等。
如何实现远程通信?
1、Webservice:效率不高基于soap协议。项目中不推荐使用。
2、使用restful形式的服务:http+json。很多项目中应用。如果服务太多,服务之间调用关系混乱。
3、使用dubbo。使用rpc协议进行远程调用,直接使用socket通信。传输效率高,并且可以统计出系统之间的调用关系、调用次数。
Dubbo
dubbo属于最后一种
Dubbo架构图:
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
调用关系说明:
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
在Monitor一层,对应了Dubbo-Admin,可以查看到监控的状态
代码配置及使用:
首先引入dubbo的相关依赖,在maven中:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
</dependency>
准备spring环境:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
好了之后在web.xml里加载spring,并读取配置文件:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
spring配置文件中开启注解扫描:
<context:component-scan base-package="cn.XXXX.service"></context:component-scan>
在提供方增加暴露服务配置<dubbo:service>,在消费方增加引用服务配置<dubbo:reference>。
下面配置提供方 <!-- 使用dubbo发布服务 -->
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="provider" />
<dubbo:registry protocol="zookeeper"
address="192.168.25.137:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.XXXX.service.ItemService" ref="itemServiceImpl" timeout="600000" />
上图意思是发布一个名叫provider的服务,使用zookeeper做注册中心,后面接了地址192.168.25.137:2181。2181是配置zookeeper时候的端口。20880是暴露服务的端口,每个服务端口不能一样。比如要配置一个provider2服务,这里服务端口可以改成20881。再下面是暴露服务的接口,消费者引入之后,可以当成自己工程的实现类用。
下面是消费者方的spring配置:
<dubbo:application name="consumer"/>
<dubbo:registry protocol="zookeeper" address="192.168.25.137:2181"/>
<dubbo:reference interface="cn.XXX.service.ItemService" id="itemService" />
同样去这个注册中心zookeeper中寻找他要的服务,因为刚刚发布过了,所以能找到。如果先启动消费者方而没有启动提供方,会报错。
最后: