Spring Cloud Bus除了支持RabbitMQ的自动化配置之外,还支持现在被广泛应用的Kafka。在本文中,我们将搭建一个Kafka的本地环境,并通过它来尝试使用Spring Cloud Bus对Kafka的支持,实现消息总线的功能。
Kafka是一个由LinkedIn开发的分布式消息系统,它于2011年初开源,现在由著名的Apache基金会维护与开发。Kafka使用Scala实现,被用作LinkedIn的活动流和运营数据处理的管道,现在也被诸多互联网企业广泛地用作为数据流管道和消息系统。
kafka简介:
Kafka是基于消息发布/订阅模式实现的消息系统,其主要设计目标如下:
消息持久化:以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。
高吞吐:在廉价的商用机器上也能支持单机每秒100K条以上的吞吐量
分布式:支持消息分区以及分布式消费,并保证分区内的消息顺序
跨平台:支持不同技术平台的客户端(如:Java、PHP、Python等)
实时性:支持实时数据处理和离线数据处理
伸缩性:支持水平扩展
Broker:Kafka集群包含一个或多个服务器,这些服务器被称为Broker。
Topic:逻辑上同Rabbit的Queue队列相似,每条发布到Kafka集群的消息都必须有一个Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个Broker上,但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
Partition:Partition是物理概念上的分区,为了提供系统吞吐率,在物理上每个Topic会分成一个或多个Partition,每个Partition对应一个文件夹(存储对应分区的消息内容和索引文件)。
Producer/ Consumer 消息生产/消费者,负责生产消息并发送到Kafka Broker,向Kafka Broker读取消息并处理
Consumer Group:每个Consumer属于一个特定的组(可为每个Consumer指定属于一个组,若不指定则属于默认组),组可以用来实现一条消息被组内多个成员消费等功能。
kafka安装:
kafka下载地址:http://kafka.apache.org/downloads.html
解压命令:tar -zxvf kafka_2.11-0.10.1.1.tgz -C /usr/local
改名命令:mv kafka_2.11-0.10.1.1/ kafka
进入解压后的目录,修改server.properties文件:
vim /usr/local/kafka/config/server.properties
修改配置文件:基于zookeeper
broker.id=0
port=9092
host.name=192.168.11.114
advertised.host.name=192.168.11.114
log.dirs=/usr/local/kafka/kafka-logs
num.partitions=2
zookeeper.connect=192.168.11.114:2181,192.168.11.115:2181,192.168.11.116:2181
qw保存退出
建立日志文件夹:mkdir /usr/local/kafka/kafka-logs
启动kafka:/usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties &
Kafka Manager 安装:
下载kafka-manager-1.0-SNAPSHOT.zip
解压:unzip kafka-manager-1.0-SNAPSHOT.zip -d /usr/local/
改名:mv kafka-manager-1.0-SNAPSHOT/ kafka-manager-1.0
编辑文件:vim /usr/local/kafka-manager-1.0/conf/application.conf
修改内容
kafka-manager.zkhosts="192.168.11.114:2181,192.168.11.115:2181,192.168.11.116:2181"
r/local/kafka/config/server.properties &
启动kafka-manager: nohup /usr/local/kafka-manager-1.0/bin/kafka-manager -Dconfig.file=/usr/local/kafka-manager-1.0/conf/application.conf >/dev/null 2>&1 &
默认端口为:9000
Kafka的shell脚本都在bin目录下。Shell使用请参考博客地址:
http://www.cnblogs.com/xiaodf/p/6093261.html
比如创建主题:
(1)创建topic主题命令:kafka-topics.sh --zookeeper 192.168.11.111:2181 --create --topic test --partitions 1 --replication-factor 1 (创建名为test的topic, 1个分区分别存放数据,数据备份总共1份)
查看主题列表:
(2)查看topic列表命令:kafka-topics.sh --zookeeper 192.168.11.111:2181 –list
生产与消费消息:
(3)kafka命令发送数据:kafka-console-producer.sh --broker-list 192.168.11.51:9092 --topic test (然后我们就可以编写数据发送出去了)
(4)kafka命令接受数据:kafka-console-consumer.sh --zookeeper 192.168.11.111:2181 --topic test (然后我们就可以看到消费的信息了)
集成:
使用bus首先两个工程引入相关依赖:spring-cloud-starter-bus-kafka
加入相关配置后,我们启动服务,并且在kafka上发现了SpringBus 这个topic主题,然后我们不需要再微服务端进行refresh刷新。
这个时候我们的上下游总线都是有针对kafka的配置,我们直接可以刷新配置中心,使用/bus/refresh刷新即可。
kafka与bus的集成 (服务端/客户端)
1. server(服务端)的pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bfxy</groupId>
<artifactId>spring-cloud-master</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-07-bus-config-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- <version>Dalston.SR5</version> -->
<version>Edgware.SR4</version>
<!-- <version>Finchley.SR1</version> -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>spring-cloud-07-bus-config-server</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.bfxy.springcloud.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件kafka必须集成zk
spring:
application:
name: bus-config-server
cloud:
config:
server:
git:
uri: https://github.com/baihezhuo/architecture-config-repo ##git地址
stream:
kafka:
binder:
zk-nodes: 192.168.11.111:2181,192.168.11.112:2181,192.168.11.113:2181 ##zk
brokers: 192.168.11.51:9092 ##kafka地址
spring:
application:
name: bus-config-server
cloud:
config:
server:
git:
uri: https://github.com/baihezhuo/architecture-config-repo ##git地址
stream:
kafka:
binder:
zk-nodes: 192.168.11.111:2181,192.168.11.112:2181,192.168.11.113:2181
brokers: 192.168.11.51:9092
server:
context-path: /
port: 4000
#关闭验证,调用本地配置中心的地址进行配置的刷新:http://localhost:4000/bus/refresh
management:
security:
enabled: false
主入口:@EnableConfigServer //开启配置中心服务
package com.bfxy.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer //开启配置中心服务
@SpringBootApplication //SpringBoot 核心配置
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2.客户端代码
pom代码
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bfxy</groupId>
<artifactId>spring-cloud-master</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-07-bus-config-client</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- <version>Dalston.SR5</version> -->
<version>Edgware.SR4</version>
<!-- <version>Finchley.SR1</version> -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>spring-cloud-07-bus-config-client</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.bfxy.springcloud.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件:(文件名必须为bootstrap.yml)
spring:
application:
name: evn
cloud:
config:
uri: http://localhost:4001/
profile: dev
label: master
stream:
kafka:
binder:
zk-nodes: 192.168.11.111:2181,192.168.11.112:2181,192.168.11.113:2181
brokers: 192.168.11.51:9092
##http://localhost:4000/{application}/{profile}/{label}
spring:
application:
name: evn
cloud:
config:
uri: http://localhost:4001/
profile: dev
label: master
stream:
kafka:
binder:
zk-nodes: 192.168.11.111:2181,192.168.11.112:2181,192.168.11.113:2181
brokers: 192.168.11.51:9092
server:
context-path: /
port: 7001
management:
security:
enabled: false
主入口:
package com.bfxy.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //SpringBoot 核心配置
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
测试端口:@RefreshScope //post方法进行手工强制刷新: http://localhost:7001/refresh
package com.bfxy.springcloud.api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope //post方法进行手工强制刷新: http://localhost:7001/refresh
@RestController
public class ConfigController {
//@Value("${from}")
private String from;
@RequestMapping(value="/from")
public String from(){
System.err.println("from: " + from);
return this.from;
}
}
使用bus集成kafka后不需要用http://localhost:7001/refresh刷新服务,只需要在server中刷新,
好处事不需要对某一个微服务进行刷新,对配置中心(服务端)进行刷信即可
http://localhost:4000/bus/refresh(需要关闭认证)服务端如下配置:
#关闭验证,调用本地配置中心的地址进行配置的刷新:http://localhost:4000/bus/refresh management: security: enabled: false
请求一个服务端请求,更新所有使用该服务端配置的客户端的配置文件
3. 分布式调用系统的现状:
当前,随着互联网架构的扩张,分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务、消息收发、分布式数据库、分布式缓存、分布式对象存储、跨域调用,这些组件共同构成了繁杂的分布式网络。