在前文的基础上,添加zookeeper集群配置
1、引入sofaBoot相关依赖
sofaBoot使用一系列后缀为-sofa-boot-starter来标识的中间件服务
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>
2、选择zookeeper作为服务注册列表,引入依赖
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
<version>0.10</version>
</dependency>
3、在application.properties中添加配置:
这里是安装在Win10上的zookeeper。
# zookeeper address list
com.alipay.sofa.rpc.registry.address=zookeeper://127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183?file=D:\\Program Files\\zookeeper\\registry
本地使用 docker 环境对 zookeeper 集群进行容器编排。多个 zookeeper 节点通过逗号分隔,file 参数指定当 zookeeper 不可用时,可以利用本地缓存文件进行服务发现
4、编写 docker-compose.yml 文件
以下配置是zookeeper小于3.5的配置,列出来加以注意。
version: '2'
services:
zoo1:
image: zookeeper:latest
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2887:3887 server.2=zoo2:2888:3888 server.3=zoo3:2889:3889
zoo2:
image: zookeeper:latest
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2887:3887 server.2=0.0.0.0:2888:3888 server.3=zoo3:2889:3889
zoo3:
image: zookeeper:latest
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2887:3887 server.2=zoo2:2888:3888 server.3=0.0.0.0:2889:3889
这里有区别,zookeeper不同版本配置不一样。zookeeper3.5及以后版本格式:server.1=0.0.0.0:2887:3887;2181,要跟上客户端端口号。生产环境里集群的所有节点,除了myid里的内容不一样,其他都一样,如:2887:3887;2181
version: '3.1'
services:
zoo1:
image: zookeeper:latest
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2887:3887;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2889:3889;2181
zoo2:
image: zookeeper:latest
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2887:3887;2182 server.2=0.0.0.0:2888:3888;2182 server.3=zoo3:2889:3889;2182
zoo3:
image: zookeeper:latest
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2887:3887;2183 server.2=zoo2:2888:3888;2183 server.3=0.0.0.0:2889:3889;2183
在安装完docker的情况下,运行docker命令,zookeeper容器集群启动。
docker-compose up -d
#结果:
Creating network "resources_default" with the default driver
Pulling zoo1 (zookeeper:latest)...
latest: Pulling from library/zookeeper
852e50cd189d: Pull complete
ef17c1a94464: Pull complete
477589359411: Pull complete
e4e48f47ca5c: Pull complete
6419278d5e83: Pull complete
374d802ad65e: Pull complete
eeeea14eefa8: Pull complete
fca066e50e37: Pull complete
Digest: sha256:6bb7ccbc809ef3595597b2257bc8400c4b80022f49466151baa02916cde0138a
Status: Downloaded newer image for zookeeper:latest
Creating resources_zoo2_1 ... done
Creating resources_zoo1_1 ... done
Creating resources_zoo3_1 ... done
启动后,在docker界面上就能看到启动的容器。
5、查看所有容器ID,或查看最近启动的容器ID
docker ps
#结果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b173441b572 zookeeper:latest "/docker-entrypoint.…" 38 seconds ago Up 36 seconds 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, 8080/tcp resources_zoo1_1
5515fd2826da zookeeper:latest "/docker-entrypoint.…" 38 seconds ago Up 36 seconds 2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2182->2181/tcp resources_zoo2_1
5dc5fbe680c6 zookeeper:latest "/docker-entrypoint.…" 38 seconds ago Up 36 seconds 2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2183->2181/tcp resources_zoo3_1
9206bafe4498 docker/getting-started "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp heuristic_tesla
6、查看完整容器信息
docker inspect 7b173441b572
7、查看zookeeper的leader
进入容器:
docker exec -it 7b173441b572 /bin/bash
进入容器运行 zkServer.sh status
逐一查看
docker exec -it 7b173441b572 /bin/bash
#结果:
root@zoo1:/apache-zookeeper-3.6.2-bin# zkServer.sh status
#结果:
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
docker exec -it 5dc5fbe680c6 /bin/bash
#结果:
zkServer.sh status
#结果:
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2183. Client address: localhost. Client SSL: false.
Mode: leader
如果还有报错,检查防火墙
#查看防火墙状态
firewall-cmd --state
#关闭防火墙
systemctl stop firewalld.service
(还有问题,具体查看/bin/zookeeper.out
日志内容,如果有这个文件的话,里面有详细的错误原因)
这样zookeeper算是整合到了docker里。
8、新增pom依赖
<!-- 新增-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
9、开始写服务提供者
目录结构:
新增sofa服务提供方配置文件
bip-sofa-service.xml
<?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:sofa="http://sofastack.io/schema/sofaboot"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"
default-autowire="byName">
<bean id="helloServiceImpl"
class="com.example.demo.service.impl.HelloServiceImpl" />
<!-- 以多种通信协议发布服务 -->
<sofa:service ref="helloServiceImpl"
interface="com.example.demo.service.IHelloService">
<sofa:binding.bolt />
<sofa:binding.rest />
<sofa:binding.dubbo />
</sofa:service>
</beans>
- 通过sofa:service元素将该服务发布,其中ref属性表示发布的服务实例,interface 属性表示该服务的接口。
- bolt: 服务通过 bolt 协协议通道发布,底层基于 Netty 实现。
- rest: 服务通过 http 协议发布。
- dubbo: 服务基于 dubbo 的协议通道发布。
10、编写服务提供者启动类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource({ "classpath:bip-sofa-service.xml" })
public class SimpleServerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SimpleServerApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
}
}
11、开始编写服务消费者
因为SOFA注册机制,测试时需要2台机子,提供者一台,消费者一台。创建消费方工程以及pom文件修改、application.properties文件配置直接参考服务提供者工程,内容一样的。需要注意的是两个工程的application.properties文件中的server.port端口不能一样。
需要消费谁提供的接口,就必须在自己工程中按提供者接口原路径新建一个一模一样的接口类。
一般都是提供者会把接口定义类给我们,我们新建好包路径,直接把提供者接口类放进去就行,包路径必须一致。
目录结构:
12、新增消费者配置文件
bip-sofa-client.xml
<?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:sofa="http://sofastack.io/schema/sofaboot"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"
default-autowire="byName">
<!-- bolt引用 -->
<sofa:reference id="boltHelloServiceReference"
interface="com.example.demo.service.IHelloService">
<sofa:binding.bolt />
</sofa:reference>
<!-- rest引用 -->
<sofa:reference id="restHelloServiceReference"
interface="com.example.demo.service.IHelloService">
<sofa:binding.rest />
</sofa:reference>
<!-- dubbo引用 -->
<sofa:reference id="dubboHelloServiceReference"
interface="com.example.demo.service.IHelloService">
<sofa:binding.dubbo />
</sofa:reference>
</beans>
13、新增消费者启动类
package com.example.demo;
import com.example.demo.service.IHelloService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
@ImportResource({ "classpath:bip-sofa-client.xml" })
@SpringBootApplication
public class SimpleClientApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SimpleClientApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
IHelloService boltHelloService = (IHelloService) applicationContext
.getBean("boltHelloServiceReference");
IHelloService restHelloService = (IHelloService) applicationContext
.getBean("restHelloServiceReference");
IHelloService dubboHelloService = (IHelloService) applicationContext
.getBean("dubboHelloServiceReference");
System.out.println("Bolt result:" + boltHelloService.sayHello("bolt"));
System.out.println("Rest result:" + restHelloService.sayHello("rest"));
System.out.println("Dubbo result:" + dubboHelloService.sayHello("dubbo"));
}
}
14、分别启动服务提供者和服务消费者,先确保docker容器正常开启和zookeeper容器正常。本机测试,为了方便服务提供者先启动完成后,再启动服务消费者。
这说明已经成功从提供者获取到了bean对象。而且在zkUI上也能看到。