西部开源 - 秦疆老师: SpringBoot + Dubbo + zookeeper
秦老师交流 Q 群号: 664386224
基础知识
分布式理论
什么是分布式系统?
在《分布式系统原理与范型》一书中有如下定义:"分布式系统是若干独立计算机的集合, 这些计算机对于用户来说就像单个相关系统";
分布式系统是由一组通过网络进行通信, 为了完成共同的任务而协调工作的计算机节点组成的系统. 分布式系统的出现是为了用廉价的, 普通的机器完成单个计算机无法完成的计算, 存储任务. 其目的是利用更多的机器, 处理更多的数据.
分布式系统 (distributed system) 是建立在网络之上的软件系统.
首先需要明确的是, 只有当单个节点的处理能力无法满足日益增长的计算, 存储任务的时候, 且硬件的提升 (加内存, 加磁盘, 使用更好的 CPU) 高昂到得不偿失的时候, 应用程序也不能进一步优化的时候, 我们才需要考虑分布式系统. 因为, 分布式系统要解决的问题本身就是和单机系统一样的, 而由于分布式系统多节点, 通过网络通信的拓扑结构, 会引入很多单机系统没有的问题, 为了解决这些问题又会引入更多的机制, 协议, 带来更多的问题...
Dubbo 文档
随着互联网的发展, 网站应用的规模不断扩大, 常规的垂直应用架构已无法应对, 分布式服务架构以及流动计算架构势在必行, 急需一个治理系统确保架构有条不紊的演进.
在 Dubbo 的官网文档有这样一张图
单一应用架构
当网站流量很小时, 只需一个应用, 将所有功能都部署在一起, 以减少部署节点和成本. 此时, 用于简化增删改查工作量的数据访问框架 (ORM) 是关键.
适用于小型网站, 小型管理系统, 将所有功能都部署到一个功能里, 简单易用.
缺点:
1, 性能扩展比较难
2, 协同开发问题
3, 不利于升级维护
垂直应用架构
当访问量逐渐增大, 单一应用增加机器带来的加速度越来越小, 将应用拆成互不相干的几个应用, 以提升效率. 此时, 用于加速前端页面开发的 web 框架 (MVC) 是关键.
通过切分业务来实现各个模块独立部署, 降低了维护和部署的难度, 团队各司其职更易管理, 性能扩展也更方便, 更有针对性.
缺点: 公用模块无法重复利用, 开发性的浪费
分布式服务架构
当垂直应用越来越多, 应用之间交互不可避免, 将核心业务抽取出来, 作为独立的服务, 逐渐形成稳定的服务中心, 使前端应用能更快速的响应多变的市场需求. 此时, 用于提高业务复用及整合的分布式服务框架 (RPC) 是关键.
流动计算架构
当服务越来越多, 容量的评估, 小服务资源的浪费等问题逐渐显现, 此时需增加一个调度中心基于访问压力实时管理集群容量, 提高集群利用率. 此时, 用于提高机器利用率的资源调度和治理中心 (SOA)[ Service Oriented Architecture] 是关键.
RPC
什么是 RPC?
RPC[Remote Procedure Call] 是指远程过程调用, 是一种进程间通信方式, 他是一种技术的思想, 而不是规范. 它允许程序调用另一个地址空间 (通常是共享网络的另一台机器上) 的过程或函数, 而不用程序员显式编码这个远程调用的细节. 即程序员无论是调用本地的还是远程的函数, 本质上编写的调用代码基本相同.
也就是说两台服务器 A,B, 一个应用部署在 A 服务器上, 想要调用 B 服务器上应用提供的函数 / 方法, 由于不在一个内存空间, 不能直接调用, 需要通过网络来表达调用的语义和传达调用的数据. 为什么要用 RPC 呢? 就是无法在一个进程内, 甚至一个计算机内通过本地调用的方式完成的需求, 比如不同的系统间的通讯, 甚至不同的组织间的通讯, 由于计算能力需要横向扩展, 需要在多台机器组成的集群上部署应用. RPC 就是要像调用本地的函数一样去调远程函数;
- [zk: 127.0.0.1:2181(CONNECTED) 4] ls /
- [zookeeper]
- server.port=7001
- spring.velocity.cache=false
- spring.velocity.charset=UTF-8
- spring.velocity.layout-url=/templates/default.vm
- spring.messages.fallback-to-system-locale=false
- spring.messages.basename=I18N/message
- spring.root.password=root
- spring.guest.password=guest
- dubbo.registry.address=zookeeper://127.0.0.1:2181
- package com.kuang.provider.service;
- public interface TicketService {
- public String getTicket();
- }
- package com.kuang.provider.service;
- public class TicketServiceImpl implements TicketService {
- @Override
- public String getTicket() {
- return "《狂神说 Java》";
- }
- }
- package com.kuang.consumer.service;
- public class UserService {
- // 我们需要去拿去注册中心的服务
- }
- <!-- Dubbo Spring Boot Starter -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>2.7.3</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
- <dependency>
- <groupId>com.GitHub.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- </dependency>
- <!-- 引入 zookeeper -->
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-framework</artifactId>
- <version>2.12.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- <version>2.12.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.14</version>
- <!-- 排除这个 slf4j-log4j12-->
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- # 当前应用名字
- dubbo.application.name=provider-server
- # 注册中心地址
- dubbo.registry.address=zookeeper://127.0.0.1:2181
- # 扫描指定包下服务
- dubbo.scan.base-packages=com.kuang.provider.service
- import org.apache.dubbo.config.annotation.Service;
- import org.springframework.stereotype.Component;
- @Service // 将服务发布出去
- @Component // 放在容器中
- public class TicketServiceImpl implements TicketService {
- @Override
- public String getTicket() {
- return "《狂神说 Java》";
- }
- }
- <!--dubbo-->
- <!-- Dubbo Spring Boot Starter -->
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>2.7.3</version>
- </dependency>
- <!--zookeeper-->
- <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
- <dependency>
- <groupId>com.GitHub.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- </dependency>
- <!-- 引入 zookeeper -->
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-framework</artifactId>
- <version>2.12.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- <version>2.12.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.14</version>
- <!-- 排除这个 slf4j-log4j12-->
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- # 当前应用名字
- dubbo.application.name=consumer-server
- # 注册中心地址
- dubbo.registry.address=zookeeper://127.0.0.1:2181
- package com.kuang.consumer.service;
- import com.kuang.provider.service.TicketService;
- import org.apache.dubbo.config.annotation.Reference;
- import org.springframework.stereotype.Service;
- @Service // 注入到容器中
- public class UserService {
- @Reference // 远程引用指定的服务, 他会按照全类名进行匹配, 看谁给注册中心注册了这个全类名
- TicketService ticketService;
- public void bugTicket(){
- String ticket = ticketService.getTicket();
- System.out.println("在注册中心买到"+ticket);
- }
- }
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class ConsumerServerApplicationTests {
- @Autowired
- UserService userService;
- @Test
- public void contextLoads() {
- userService.bugTicket();
- }
- }
来源: https://www.cnblogs.com/hellokuangshen/p/11330606.html