1.Dubbo调用流程图
图中组件介绍:
1.Consumer消费者:
接口的调用者就是消费者
2.Provider生产者
服务的具体的实现方,实现类所在的位置
3.registy注册中心
管理服务器地址
内部有心跳检测机制,可以返回给客户端真实有效的服务器地址,使其访问永久有效.
4.Monitor监控中心
可以通过页面的形式非常直观的查看当前Dubbo中服务的状态.
2.传统的问题:如果客户端通过ip地址直连的方式调用服务时,如果后台的服务器发生了宕机的现象,则客户端调用一定报错.
如何改进:
1.引入注册中心zookeeper.为了实现宕机后故障快速迁移必须有心跳检测.
2.引入服务自动发现功能,如果机器修复完成后,再次添加到注册中心中.
3.dubbo工作原理图
当服务端程序启动时,会将服务端的信息(接口的名称/方法名/IP/端口)写入到注册中心.
当客户端程序启动时,首先会连接注册中心,获取全部的服务列表信息,保存到redis中.
一、来一手测试:
接口
public interface IProcessData{
public String hello(String name);
}
实现类:
public class ProcessDataImpl implements IProcessData { public String hell(String name) {
return "service hellp:" + name;
}
编辑服务端配置文件
<!-- 生产者应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<!-- <dubbo:registry address="multicast://123.4.5.6:1234"/> -->
<dubbo:registry address="zookeeper://192.168.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jt.dubbox.api.IProcessData" ref="demoService" />
<!-- 具体的实现bean -->
<bean id="demoService" class="com.jt.dubbox.service.impl.ProcessDataImpl" />
服务端测试类程序:
public class Main {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationProvider.xml" });
//注意不能用ApplicationContext接口
context.start();
System.out.println("service1 started!");
System.out.println("按任意键退出");
System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟
}
}
客户端配置文件:
<?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="consumer-of-helloworld-app" />
<!-- 注册中心暴露服务地址 -->
<!-- <dubbo:registry address="multicast://123.4.5.6:1234"/> -->
<dubbo:registry address="zookeeper://192.168.0.1:2181" />
<dubbo:consumer timeout="5000"/>
<!-- 生成远程服务代理,可以像使用本地bean一样使用demoService -->
<dubbo:reference id="demoService" interface="com.jt.dubbox.api.IProcessData" />
</beans>
客户端测试类程序:
public class ConsumerThd {
public static void main(String[] args) {
sayHello();
}
public static void sayHello() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationConsumer.xml" });
context.start();
IProcessData demoService = (IProcessData) context.getBean("demoService");
for (;;) {
String s = demoService.hello("188");
System.out.println(s);
}
}
}
二、在项目中引入dubbo,重构购物车项目
说明:由于duboo的项目的jar包如果直接导入jt-parent中会导致原有的项目可能出现问题.所以采用jt-dubbo-parent继承jt-parent的方式,将全部的dubbo的jar包文件写入jt-dubbo-parent中,之后的全部的dubbo项目继承jt-dubbo-parent即可.
1.修改继承和打包类型
说明:修改完成后将项目更新 maven-update
<dependencies>
<!--dubbo依赖 -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.15.0-GA</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-core</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.39</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.bsf</groupId>
<artifactId>bsf-api</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>1.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.7</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jdk-http</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.24.0</version>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.26</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>1.55</version>
</dependency>
</dependencies>
<parent>
<groupId>com.1.188</groupId>
<artifactId>1-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
创建jt-dubbo-common
将原有工具类中的文件导入后,将项目打包
说明:创建第三方接口的工具项目.在工具项目中需要定义接口文件和pojo对象
<parent>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
1.定义pojo对象
说明:将cart中的cart对象复制后保存到jt-dubbo-api中
@Table(name="tb_cart")
public class Cart extends BasePojo {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
......(各种字段)
}
2.定义cart接口
public interface DubboCartService {
List<Cart> findCartByUserId(Long userId);
void saveCart(Cart cart);
void updateCartNum(Cart cart);
void deleteCart(Long userId, Long itemId);
}
将接口项目打包
<!--项目原有依赖-->
<parent>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--dubbo生产者依赖文件 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<!--通用mapper-->
<groupId>com.github.abel533</groupId>
<artifactId>mapper</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8094</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
生产者配置文件:
<!-- 生产者应用信息,用于计算依赖关系 -->
<dubbo:application name="jt-cart" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.0.1:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jt.dubbo.service.DubboCartService" ref="cartService" />
<!-- 具体的实现bean -->
<bean id="cartService" class="com.jt.cart.service.DubboCartServiceImpl" />
<!--项目原有依赖-->
<parent>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--dubbo消费者依赖文件 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<!--通用mapper-->
<groupId>com.github.abel533</groupId>
<artifactId>mapper</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8092</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
添加消费者配置文件
<dubbo:application name="jt-web"/>
<dubbo:registry address="zookeeper://192.168.0.1:2181" />
<!--
check=false 表示启动时不检查是否有生产者, 只有调用时才检查
id 应该和生产者给定的接口id一致
interface 表示生产者的路径
-->
<dubbo:reference check="false" id="cartService" interface="com.jt.dubbo.service.DubboCartService" timeout="10000"/>
cart展现的业务代码:
@Controller
@RequestMapping("/cart")
public class CartController {
@Autowired
private DubboCartService cartService;
//跳转到购物车展现页面
@RequestMapping("/show")
public String findCartById(Model model){
Long userId = UserThreadLocal.get().getId();
List<Cart> cartList = cartService.findCartByUserId(userId);
model.addAttribute("cartList", cartList);
return "cart";
}
}
测试访问:www.jt.com/cart/show.html
三、在项目中引入dubbo,重构订单系统
<parent>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jt.188</groupId>
<artifactId>jt-dubbo-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--dubbo生产者依赖文件 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<!--通用mapper-->
<groupId>com.github.abel533</groupId>
<artifactId>mapper</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8095</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
定义order接口
public interface DubboOrderService {
public String saveOrder(Order order);
public Order findOrderById(String orderId);
}
修改mybastis配置文件
26行:<property name="typeAliasesPackage" value="com.jt.dubbo.pojo"/>
编辑生产者配置文件(和cart的生产者除了系统名字不一样其他都一样)
<!-- 生产者应用信息,用于计算依赖关系 -->
<dubbo:application name="jt-order" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.0.1:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20881" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.jt.dubbo.service.DubboOrderService" ref="orderService" />
<!-- 具体的实现bean -->
<bean id="orderService" class="com.jt.order.service.OrderServiceImpl" />
编辑消费者配置文件
<dubbo:application name="jt-web"/>
<dubbo:registry address="zookeeper://192.168.0.1:2181" />
<!--
check=false 表示启动时不检查是否有提供者, 只有调用时才检查
id 应该和提供者给定的接口id一致
interface 表示生产者的路径
-->
<dubbo:reference check="false" id="cartService" interface="com.jt.dubbo.service.DubboCartService" timeout="10000"/>
<dubbo:reference check="false" id="orderService" interface="com.jt.dubbo.service.DubboOrderService" timeout="10000"/>
order展现的业务代码
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private DubboCartService cartService;
//跳转到订单确认页面
@RequestMapping("/create")
public String create(Model model){
Long userId = UserThreadLocal.get().getId();
//获取购物车数据
List<Cart> cartList = cartService.findCartByUserId(userId);
model.addAttribute("cartList", cartList);
return "order-cart";
}
}
测试访问:www.jt.com/order/create.html