1、分布式理论

1.1)什么是分布式系统

“分布式是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”
分布式系统是建立在网络之上的软件系统

1.2)发展演变

image.png
单一应用架构—-》垂直应用架构—-》分布式业务架构—》流动计算架构
image.pngimage.png

  1. 1.界面+业务逻辑的实现分离
  2. 2.应用不可能完全独立,大量的应用之间需要交互。

image.pngimage.png

1.3)RPC

什么是RPC
RPC [ Remote Procedure Call]是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另-台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
RPC原理图
image.png
例子:
image.png

影响一个RPC框架的性能的两点核心模块(通信[xml,json,二进制流 ]和序列化)
能否在各个调用之间快速的建立连接(看框架的序列化机制和反序列化机制快不快)

市面上的RPC框架:dubbo,gRPC,Thrift,HSF(High Speed Service Framework)

2、dubbo核心概念

2.1)简介

Apache Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现
官网:https://dubbo.apache.org/zh/index.html
特性:
image.png

为动态感知每一个服务的健康状态引入注册中心。
image.png
灰度发布:由旧服务慢慢的变为新服务,先将部分旧服务替换为新服务,当一段时间后没有问题再将一部分替换为新服务从而将所有的服务都替换为新服务。

2.2)dubbo设计架构

image.png
https://blog.csdn.net/niyuelin1990/article/details/103974106
image.png

3、启动服务注册中心

启动报错:缺少配置文件
image.pngimage.png
修改配置文件数据存放位置:dataDir=../data
再次启动:启动OK。
image.png

4、安装监控中心

监控中心可不安装。不影响使用
image.png
下载地址
Dubbo Admin下载,mvn clean package进行打包。2.8以前是war包,2.8以后是jar包。
启动监控中心:java -jar xxxx.jar
默认端口:7001,用户名和密码都是root
image.png
image.png

5、dubbo-helloworld

5.1)需求如下

某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址
我们现在,需要创建两个服务模块进行测试。

  • 订单服务web模块:创建订单等
  • 用户服务service模块:查询用户地址

测试预期结果:订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。
image.png

5.2)创建SpringBoot工程 dubbo-demo

5.3)创建服务提供者 user-service-provider

  1. public class UserAdress implements Serializable {
  2. private Integer id;
  3. private String userAdress; // 用户地址
  4. private String userId; // 用户id
  5. private String consignee; // 收货人
  6. private String phoneNume; // 电话号码
  7. private String isDefault; // 是否为默认地址
  8. }
  1. public interface UserService {
  2. /**
  3. * 获取用户所有地址
  4. * @param userId
  5. * @return
  6. */
  7. List<UserAdress> getUserAddressList(String userId);
  8. }
  1. public class UserServiceImpl implements UserService {
  2. @Override
  3. public List<UserAdress> getUserAddressList(String userId) {
  4. UserAdress userAdress1 = new UserAdress(1, "长沙", "1", "李老师", "199", "是");
  5. UserAdress userAdress2 = new UserAdress(2, "长沙", "2", "谭老师", "198", "是");
  6. return Arrays.asList(userAdress1, userAdress2);
  7. }
  8. }

5.4)创建订单服务 order-service-consumer

  1. public interface OrderService {
  2. /**
  3. * 初始化订单
  4. * @param userId
  5. */
  6. public void initOrder(String userId);
  7. }
  1. public class OrderServiceImpl implements OrderService {
  2. @Override
  3. public void initOrder(String userId) {
  4. // 1. 查询用户的地址
  5. List<UserAdress> userAddressList = userService.getUserAddressList(userId);
  6. System.out.println(userAddressList);
  7. }
  8. }

5.5)创建公共服务 gmail-interface

将实体类和接口放入到公共服务模块中,并引入公共模块依赖。

最后的项目结构如下:
image.png

6、dubbo改造helloworld

provider.xml:https://dubbo.apache.org/zh/docsv2.7/user/quick-start/
zookeeper注册中心:https://dubbo.apache.org/zh/docsv2.7/user/references/registry/zookeeper/
步骤:

6.1)配置服务提供者

user-service-provider工程中添加provider.xml配置。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
  6. <!-- 1、提供方应用信息,用于计算依赖关系 -->
  7. <dubbo:application name="user-service-provider" />
  8. <!-- 2、指定注册中心,使用zookeeper广播注册中心暴露服务地址 -->
  9. <!-- 集群配置-->
  10. <!-- <dubbo:registry address="zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181" />-->
  11. <!-- 单机配置 <dubbo:registry address="zookeeper://10.20.153.10:2181" /> -->
  12. <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />
  13. <!-- 3、指定通信规则,用dubbo协议在20880端口暴露服务 -->
  14. <dubbo:protocol name="dubbo" port="20880" />
  15. <!-- 4、声明需要暴露的服务接口, userService指向服务真正的实现对象 -->
  16. <dubbo:service interface="com.lzy.service.UserService" ref="userServiceImpl" />
  17. <!-- 5、和本地bean一样实现服务 -->
  18. <bean id="userServiceImpl" class="com.lzy.service.impl.UserServiceImpl" />
  19. </beans>

user-service-provider工程中添加MainApplication入口类进行测试

  1. public class MainApplication {
  2. public static void main(String[] args) throws IOException {
  3. ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
  4. ioc.start(); // start是ClassPathXmlApplicationContext中的方法
  5. System.in.read();
  6. }
  7. }

启动后:
image.png

image.png

6.2)配置服务消费者

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  8. http://dubbo.apache.org/schema/dubbo
  9. http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
  10. <!-- 让注解生效,使用包扫描-->
  11. <context:component-scan base-package="com.lzy.service.impl"></context:component-scan>
  12. <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
  13. <dubbo:application name="order-service-consumer" />
  14. <!-- 使用zookeeper广播注册中心暴露发现服务地址 -->
  15. <dubbo:registry address="zookeeper://127.0.0.1:2181" />
  16. <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
  17. <dubbo:reference id="userService" interface="com.lzy.gmail.service.UserService" />
  18. </beans>
  1. import com.lzy.gmail.service.OrderService;
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;
  3. import java.io.IOException;
  4. public class MainApplication {
  5. public static void main(String[] args) throws IOException {
  6. ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
  7. OrderService orderService = ioc.getBean(OrderService.class);
  8. orderService.initOrder("1");
  9. System.out.println("调用完成~");
  10. System.in.read();
  11. }
  12. }

启动测试:
image.png

6.3)监控中心:dubbo-monitor-simple

打包:mvn clean package
image.png
打包后不要直接启动,将压缩包解压后,修改下dubbo.properties配置文件后,进入bin目录进行启动。
image.png
image.png

添加监控中心地址
image.png

  1. <!-- 添加监控中心 protocol="registry" 去注册中心发现-->
  2. <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>
  3. <!-- <dubbo:monitor protocol="registry"></dubbo:monitor>-->

重新启动服务
image.png

7、与SpringBoot整合

导入依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.boot</groupId>
  7. <artifactId>dubbo-spring-boot-starter</artifactId>
  8. <version>0.2.0</version>
  9. </dependency>

创建订单controller

  1. @RestController
  2. public class OrderController {
  3. @Autowired
  4. private UserService userService;
  5. @RequestMapping("/initOrder")
  6. public List<UserAdress> initOrder(@RequestParam("uid")String userId) {
  7. return userService.getUserAddressList(userId);
  8. }
  9. }

使用application.properties整合dubbo

  1. dubbo.application.name=user-service-provider
  2. dubbo.registry.address=127.0.0.1:2181
  3. dubbo.registry.protocol=zookeeper
  4. # 协议
  5. dubbo.protocol.name=dubbo
  6. dubbo.protocol.port=20880
  7. # 使用注册中心发现
  8. dubbo.monitor.protocol=registry

暴露服务使用注解@Service [import com.alibaba.dubbo.config.annotation.Service;]
主程序开启dubbo。@EnableDubbo # 开启注解的Dubbo功能。

  1. import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @EnableDubbo // 开始Dubbo注解
  5. @SpringBootApplication
  6. public class MainApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(MainApplication.class);
  9. }
  10. }

启动测试访问地址: http://localhost:8902/initOrder?uid=1
image.png
image.png