本文纯个人读书笔记,书籍《一步一步学 Spring Boot 2》
如果喜欢,可直接购买书籍。如有侵权,请联系删除
一、Zookeeper
1.概述
ZooKeeper 是一个开源的分布式应用程序协调服务,提供的功能包括命名服务、配置管理 、 集群管理、分布式锁等 。
( 1 )命名服务 : 可以简单理解为电话簿 。 电话号码不好记,但是人名好记 。要打谁的电话 , 直接查人名就好了 。在分布式环境下,经常需要对应用 /服务进行统一命名,便于识别不同服务。类似于域名与 IP 之间的对应关系,域名容易记住。ZooKeeper 通过名称来获取资源或服务的地址、提供者等信息。
( 2 )配置管理: 分布式系统都有大量服务器,比如在搭建 Hadoop 的 HDFS 的时候,需要在一台 Master 主机器上配置好 HDFS 需要的各种配置文件 , 然后通过 scp 命令把这些配置文件复制到其他节点上,这样各个机器拿到的配置信息是一致的,才能成功运行 HDFS 服务。 Zookeeper 提供了这样 的服务: 一种集中管理配置 的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣的都可以获得变更。这样就省去于动复制配置 , 还保证了可靠和一致性。
( 3 )集群管理: 集群管理包含两点 : 是否有机器退出和加入 、选举 Master。在分布式集群中,经常会由于各种原因(比如硬件故障、软件故障、网络问 题等〉 ,有些新的节点会加入进来,也有老的节点会退出集群。这个时候,集群中有些机器( 比如 Master 节点) 需要感知到这种变化, 然后根据这种变 化做出对应的决策 。Zookeeper 集群管理就是感知变化,做出对应的策略。
( 4 )分布式锁: Zookeeper 的一致性文件系统使得锁的问题变得容易 。 锁服务可以分为两类, 一类是保持独占,另 一类是控制时序 。单机程序的各个进程对互斥资源进行访问时需要加锁,分布式程序分布在各个主机上的进程对互斥资源进行访问时也需要加锁 。 很多分布式系统有多个可服务的窗口,但是在某个时刻只让一个服务去干活 , 当这台服务出 问题的时候锁释放,立即 fail over 到另外 的服务。在很多分布式系统中都是这么做的,这种设计有一个更好听的名字 Leader Election ( Leader 选举)。举个通俗点 的例子,比如去银行取钱,有多个窗口 ,但是只能有一个窗口对你服务。如果正在对你服务的窗口的柜员突然有急事走了,怎么办呢?找大堂经理( Zookeeper),大堂经理会指定另 外的窗口继续为你服务。
Zookeeper 的一个最常用的使用场景是担任服务生产者和服务消费者的注册中心,这也是接下来会使用到的 。 服务生产者将自己提供的服务注册到 Zookeeper 中心,服务消费者在进行服务调用的时候先到 Zookeeper 中查找服务,获取服务生产者的详细信息之后,再去调用服务生产者的内容与数据。
概念来自书中原文。
2.安装与启动
到 官网链接 进行下载。
解压出来,到 conf 文件夹下,把 zoo_sample.cfg 复制一份,并重命名为 zoo.cfg(Zookeepe 启动时会默认在 conf 目录下读取 zoo.cfg 配置文件)。
点击 bin 文件夹下的 zkServer.cmd 进行启动。
二、Spring Boot 集成 Dubbo
1.Dubbo
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成。
Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Registry 是服务注册与发现的注册中心, Provider 是暴露服务的服务提供方,Consumer 是调用远程服务的服务消费方, Monitor 是统计服务的调用次数和调用时间的监控中 心, Container 是服务运行容器。
( 1 )服务容器 Container 负责启动、 加载、 运行服务提供者 Provider 。
( 2 )服务提供者 Provider 在启动时,向注册中心 Registry 注册自己提供的服务。
( 3 )服务消费者 Consumer 在启动时,向注册中心 Registry 订阅自己所需的服务 。
( 4 )注册中心 Registry 返回服务提供者地址列表给消费者 Provider , 如果有变更,注册中心 Registry 将基于长连接推送,变更数据给消费者 Consumer 。
( 5 )服务消费者 Consumer 从提供者地址列表中基于软负载均衡算法选一 台提供者进行调用,如果调用失败,就再选另一台调用 。
( 6 )服务消费者 Consumer 和提供者 Provider 在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心 Monitor。
2.接口与服务拆分
对于 my-spring-boot 的真实的项目来说, my-spring-boot 这个大的服务承载的内容太多,诸多服务接口(比如 UserService 、 MoodService 、RoleService 等)合在一起对外提供服务己经违背了微服务理念。因此, 我们有必
要对 my-spring-boot 项目进行服务拆分,使它被拆分成一个个小的服务 , 我们可以按业务或者功能维度对服务进行拆分。
3.创建 Module
右击项目,单击 New → Module ,
在弹出的窗口中选择 Spring lnitializr, 然后单击 Next 按钮。
在 Artifact 和 Name 输入框中输入模块的名称 user-api,其他选项保持默认即可。然后单击 Next 按钮。
一路单击 Next 按钮, 在 Module name 输入框中填入模块的名称 use-api,然后单击 Finish 按钮。
按这个步骤,分别创建用户和角色的接口模块 user-api、role-api,以及服务模块 user-service、role-service。
注: 在实际项目中,user-api 和 user-service 为 user 模块,单独建一个项目,role-api 和 role-service 为角色模块,单独建一个项目。这边为了方便,直接放在一个项目里。
最后,各个模块的代码写到对应的包下。
4.接口模块
在 user-api 下进行接口的开发。
新建实体类 com.xiaoyue.demo.model.User。
User:
public class User implements Serializable {
private String id;
private String name;
private String password;
......
}
新建接口类 com.xiaoyue.demo.api.UserDubboService。
UserDubboService :
public interface UserDubboService {
User findByUserNameAndPassword(String name , String password);
}
5.发布
user-api 模块接口开发完成之后,就可以将其发布成正式版 jar 包。 jar 包有快照版 SNAPSHOT 和正式版 。 我们创建的模块 user-api 模块默认就是快照版 0.0.1-SNAPSHOT。 快照版的模块是可以重复修改的, 而正式版的模块不可以修改。
在开发过程中,模块基本都是 SNAPSHOT 版。当模块开发并测试完成后,会升级为正式版 ,而且在项目上线的时候,依赖的模块都必须是正式版 , 否则会出现意想不到的错误 。我们可以在 porn 文件中修改模块的版本,比如把user-api 修改成 0.0.1 正式版。
1. 修改 pom.xml 中的版本为 0.0.1。
2. 在 lntelliJ IDEA 开发工具右侧的 Maven 中,分别单击 clean、install,将 user-api 以 jar 包发布布到本地 Maven 仓库。
3. 发布正式版 jar 后,其他模块就可以直接引用,也可以在 Maven 的仓库进行查看。
6.服务模块
我们继续开发 User 的服务模块 user-service。
1. 引入 user-api 的依赖和 Dubbo 依赖 。添加 user-api 的依赖是因为 user-servic 模块是面向接口编程的,而添加 Dubbo 依赖是因为服务开发完成之后, 要把该服务注册到 Zookeeper 中。
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.xiaoyue</groupId>
<artifactId>user-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
2. 创建服务实现类 com.xiaoyue.demo.service.UserDubboServicelmpl 。
UserDubboServicelmpl :
@Service(version="1.0")
public class UserDubboServicelmpl implements UserDubboService {
@Override
public User findByUserNameAndPassword(String name, String password) {
//实际项目可以去数据库获取
User user =new User() ;
user.setName("zx");
user.setPassword("123456") ;
return user ;
}
}
@Service:这个注解是在 com.alibaba.dubbo.config.annotation.Service 包下的。添加 @Service 注解就可以把 UserDubboServicelmpl 类注册到 Zookeeper 服务中心,对外提供服务。 version 属性用于指定服务的版本,这里服务版本为 1.0 , 当一个接口出现不兼容升级时,可以用版本号 version 过渡,版本号不同的服务互不引用 。
7.服务注册
user-service 模块开发完成之后,可以单独运行它 。找到 user-service 模块的入口 类 UserServiceApplication (确保 Zookeeper 是启动状态〉,执行入口类的 main 方法便可以启动 user-service 服务。
注: 按作者书上这时候启动时可以成功的,我这边试了一下,好像不能启动成功。有可能是没用使用这个,不熟,看的没有很懂。
8.客户端开发
在客户端添加 user-api 的依赖和 Dubbo 依赖。
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.xiaoyue</groupId>
<artifactId>user-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
<version>1.0.0</version>
</dependency>
可以直接在客户端进行引用。
@Reference (version = "1.0")
public UserDubboService userDubboService ;
@Reference 注解也是 Dubbo 框架提供 的, 在 com.alibaba.dubbo.config.annotation.Reference 包下 。 version 是 @Reference 注解的属性, version 的版本需要和 @Service 注解的 version 版本保持一致,否则服务将无法注入。
注: 根据这个步骤最后没跑起来,作者也没有进行后续的测试步骤,不确定是否完成。这本书快完了,就不再这边进行深究,后续自己再去研究。