dubbo从入门到实战
1 互联网系统架构演变
随着互联网的发展,网站应用规模不断壮大,由此系统架构也在不断演变,下图是一张经典的演变过程图:
单一应用架构
优点:当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本
缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护
此时:用于简化增删改查工作量的数据访问框架(ORM)是关键
垂直应用架构
优点:解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率
缺点:但是在垂直架构中相同逻辑代码需要不断的复制,不能复用。
此时:用于加速前端页面开发的Web框架(MVC)是关键
分布式应用架构(RPC)
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心
此时:用于提高业务复用及整合的分布式服务框架(RPC)是关键
流动计算架构(SOA)
随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架
此时,用于提高机器利用率**资源调度和治理中心(SOA)**是关键。
2 什么是Dubbo
Dubbo是一个微服务开发框架,提供了RPC通信与微服务治理两大关键能力。它提供了远程过程调用的能力,使得远程调用像本地调用一样方便
Dubbo提供的基础能力包括:
- 服务发现
- 流式通信
- 负载均衡
- 流量治理
- 集群容错
- 服务降级
- …
3 Dubbo总体架构
以下是官网的一张图
节点 | 说明 |
---|---|
Consumer | 需要调用远程服务的服务消费方 |
Registry | 注册中心 |
Provider | 服务提供方 |
Container | 服务运行的容器 |
Monitor | 监控中心 |
通过上图,可以知道服务发现整体流程如下:
- 服务提供者Provider启动然后向注册中心注册自己所能提供的服务。
- 消费者Consumer启动向注册中心订阅所需的服务。
- 然后注册中心返回服务提供者地址列表给消费者Consumer,如果有变更,注册中心将基于长连接推送变更数据给消费者Consumer。
- 消费者Consumer就可以负载均衡选择一个Provier直接调用。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4 快速入门
新建两个Maven项目,JDK版本1.8,Dubbo版本2.7,一个消费者,一个提供者
引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo</artifactId>
<groupId>com.tiza.leo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo_001_p</artifactId>
<!--引入依赖-->
<dependencies>
<!-- core context beans spring三件套-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<!-- dubbo 2.5.3-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
<!-- zookeeper zkclient-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>提供端代码
UserService
1
2
3
4
5
6
7
8package com.w1nd.dubbo.service;
public interface UserService {
public String findName(String name);
public void addUser(String username);
}UserServiceImpl
1
2
3
4
5
6
7
8
9
10
11
12
13package com.w1nd.dubbo.service;
public class UserServiceImpl implements UserService {
public String findName(String name) {
System.out.println("姓名:" +name);
return "hello: "+name;
}
public void addUser(String username) {
System.out.println("添加用户,用户名为: "+username);
}
}spring-dubbo.xml(重要)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<?xml version="1.0" encoding="UTF-8"?>
<!--suppress SpringFacetInspection -->
<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">
<!--通过duboo发布服务 -->
<dubbo:application name="dubbo_001_p"></dubbo:application>
<!--将服务注册到指定的注册中心-->
<dubbo:registry address="multicast://224.5.6.7:1234"></dubbo:registry>
<!--指定服务的协议 和 使用端口号 注意此处服务端使用客户端无需使用 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<dubbo:provider timeout="5000"></dubbo:provider> <!--定义超时时间方式一-->
<!--注册服务到注册中心-->
<dubbo:service interface="com.w1nd.dubbo.service.UserService" ref="userService" timeout="4000"> <!--定义超时时间方二-->
<dubbo:method name="findName" timeout="3000"></dubbo:method> <!--定义超时时间方式三-->
</dubbo:service>
<!--服务提供者-->
<bean id="userService" class="com.w1nd.dubbo.service.UserServiceImpl"></bean>
</beans>测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package com.w1nd.dubbo.publish;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import static org.junit.Assert.*;
public class PublishServiceTest {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo.xml");
System.out.println("服务提供者,开始提供服务.....");
System.in.read();
}
}消费端代码
UserService
1
2
3
4
5
6
7package com.w1nd.dubbo.service;
public interface UserService {
public String findName(String name);
public void addUser(String username);
}spring-dubbo.xml(重要)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<?xml version="1.0" encoding="UTF-8"?>
<!--suppress SpringFacetInspection -->
<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消费服务-->
<dubbo:application name="dubbo_001_c"/>
<!--指定的注册中心-->
<dubbo:registry address="multicast://224.5.6.7:1234"></dubbo:registry>
<!--关闭所有服务的启动时检查 (没有提供者时报错):-->
<dubbo:consumer timeout="5000" ></dubbo:consumer> <!--定义超时时间方式一-->
<!--调用服务-->
<dubbo:reference id="userService" interface="com.w1nd.dubbo.service.UserService" timeout="4000" > <!--定义超时时间方式二-->
<dubbo:method name="findName" timeout="3000"></dubbo:method> <!--定义超时时间方式三-->
</dubbo:reference>
</beans>测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.w1nd.dubbo.invoke;
import com.w1nd.dubbo.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InvokeServiceTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo.xml");
UserService userService = (UserService) context.getBean("userService");
userService.addUser("w1nd");
/* String serverReturn = userService.findName("GouSheng");
System.out.println("get message from server message is " + serverReturn);*/
}
}
5 集群
不同消费者的使用端口号设置不一样,即可。
dubbo_cluster_001_p
1 |
|
dubbo_cluster_002_p
1 |
|
dubbo_cluster_003_p
1 |
|