文章目录
Spring cloud config配置中心
默认用git仓库进行存储数据
步骤
- 创建远程仓库
1.在gitee中,右上角点加号
2.设置仓库名
3.设置成开源项目 - 创建本地仓库
VCS----create git repository
选择springcloud1工程文件夹作为本地仓库目录
点击对勾即可或ctrl+k
选中全部文件、必写提交信息、执行提交 - 把本地仓库的数据上传到远程仓库
ctrl+shift+k 或VCS----git----push 执行推送
点击define remote
粘贴远程仓库的地址
三个业务模块的配置,传到git仓库
- 在springcloud1创建一个目录
- 复制三个业务的application.yml进去这目录
- 三个文件中添加override-none=true
spring:
application:
name: order-service
cloud:
config:
override-none: true
防止下载的配置,覆盖本地参数设置
4. 提交到本地仓库
5. 上传到远程仓库
搭建配置中心
- 新建sp09-config模块
- 添加config server 、eureka client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- yml配置
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://gitee.com/han-jia-ajie/springcloud1
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
- 启动类注解:@EnableConfigServer
- 检查确认:http://localhost:6001/item-service/dev
http://localhost:6001/user-service/dev
http://localhost:6001/order-service/dev
配置中心的客户端
- 修改2,3,4的application.yml的代码全部注释
- 修改03用户,添加配置中心客户端设置
添加config client依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
新建bootstrap.yml(在引导配置阶段,从配置中心下载)
添加三条配置:
连接eureka
指定配置中心的服务ID
从配置中心下载user-service-dev.yml
#连接eureka
eureka:
client:
service-url:
#默认地点,如果使用的是云服务,可以通过云服务商购买不同地点的注册中心服务器
#自己搭建的注册中心只能使用defaultZone
defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
#配置中心的服务id
spring:
cloud:
config:
discovery:
enabled: true
service-id: config-server
#user-service-dev.yml
name: order-service
profile: dev
#下载配置文件
Rabbitmq消息中间件
在分布式系统中,用来在模块之间传递数据的工具,是重要的组件,RabbitMQ是一种消息中间件,用于处理来自客户端的异步消息。
常见的消息服务器:Rabbitmq、Acticemq、Kafka、Rocketmq(阿里)、Tubemq(腾讯)
搭建Rabbitmq服务器(需要VMware)
VMware
版本要在16或16+
NatW网络网段
使用192.168.64.0网段
(编辑—>虚拟网络编辑–上面选择vmnet8—左下角修改成192.168.64.0)
安装 Docker 虚拟机
- 关闭 centos-8-2105
- 克隆 centos-8-2105: docker-base
- 用 mobaxterm 工具上传文件到 /root/
– 课前资料\DevOps课前资料\docker\docker-install 文件夹(可以用上个老师的软件) - 参考 Docker离线安装笔记,从第3步开始执行(前两步下载文件不用执行)
点这个连接
Rabbitmq 消息中间件
在分布式系统中,用来在模块之间传递数据的工具
消息服务在分布式系统中,是非常重要的组件
常用的消息服务器:
- Rabbitmq
- Activemq
- Kafka
- Rocketmq
- Tubemq
- …
搭建 Rabbitmq 服务器
- 准备好docker环境
- 从 docker base 克隆: rabbitmq
- 设置ip地址
./ip-static ip: 192.168.64.140 ifconfig #如果有问题,参考 VMware 下面的 解决网络设置问题
- 上传镜像压缩文件到/root/
–DevOps课前资料\docker\rabbitmq-image.gz` - 执行导入
docker load -i rabbitmq-image.gz
具体看这个链接
Rabbitmq 服务的六种模式:
简单模式
1. pom文件:
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.4.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.生产者发送消息
package m1;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//1.连接服务器
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("wht6.cn");//要和自己的虚拟机ip匹配
factory.setPort(5672);//5672是客户端收发信息的端口,15672是管理控制台的访问端口
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();//通信的通道
//2.创建队列 helloworld,如果已经存在就不会重复创建
//queueDeclare:队列声明
/**
* 队列的名字
* 队列的三个布尔值属性:
* 是否是持久队列
* 是否是排他队列(独占队列)
* 是否自动删除
*
* null--队列的其他属性
* */
channel.queueDeclare("helloworld-ren",false,false,false,null);
//3.向holloworld
/**
* 第一个参数"":默认的交换机
* 第二个参数:队列的名字
* 第三个参数null:消息的其他参数属性
* 第四个参数:消息的内容
* */
channel.basicPublish("", "helloworld-ren", null, "helloworld".getBytes());
System.out.println("消息发送完成");
}
}
3.消费者接收消息
package m1;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
//建立连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("wht6.cn");//要和自己的虚拟机ip匹配
factory.setPort(5672);//5672是客户端收发信息的端口,15672是管理控制台的访问端口
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//创建队列
channel.queueDeclare("helloworld-ren",false,false,false,null);
//创建回调对象
DeliverCallback deliverCallback= (consumerTag,message)->{
byte[] a = message.getBody();
String s = new String(a);
System.out.println("收到:"+s);
};
CancelCallback cancelCallback=consumerTag -> {};
//从helloworld接收消息,传递回调对象
/**
* 第二个参数true:autoAck - 自动确认 auto Acknowledge
* */
channel.basicConsume("helloworld-ren", true,deliverCallback,cancelCallback);
}
}
工作模式
生产者发送消息
package m2;
import com.rabbitmq.client.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("wht6.cn");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin" );
//创建队列,叫helloworld-ren
Channel channel = connectionFactory.newConnection().createChannel();
channel.queueDeclare("task_queue", true,false,false , null);
//发送消息
while (true){
System.out.println("输入消息:");
String s = new Scanner(System.in).next();
channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_BASIC, s.getBytes());
}
}
}
消费者接收消息
package m2;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
//连接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("wht6.cn");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin" );
//创建队列
Channel channel = connectionFactory.newConnection().createChannel();
//创建回调对象
DeliverCallback deliverCallback= (consumerTag,message)->{
String s = new String(message.getBody());
System.out.println("收到:"+s);
//遍历字符串找‘.’字符
for (int i = 0; i <s.length() ; i++) {
if (s.charAt(i)=='.'){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("-------------消息处理完成------------");
//第一个:回执
//第二个:是否确认之前收到过的所有消息
channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
};
CancelCallback cancelCallback=consumerTag -> {};
//每次收一条,处理完之前不受下一条
channel.basicQos(1);
//开始接收数据
channel.basicConsume("helloworld-ren", true, deliverCallback, cancelCallback);
}
}
广播模式(订阅模式)
交换机类型是扇形
生产者发送消息
package m3;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//连接
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("wht6.cn");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin" );
Channel channel = connectionFactory.newConnection().createChannel();
//创建Fanout交换机:logs
//channel.exchangeDeclare("logs", "fanout");
channel.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
//向logs交换机发送消息
while (true){
System.out.println("输出消息:");
String s = new Scanner(System.in).nextLine();
channel.basicPublish("logs", "", null, s.getBytes());
}
}
}
消费者接收消息
package m3;
import com.rabbitmq.client.*;
import jdk.nashorn.internal.parser.Scanner;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException {
//连接
ConnectionFactory f = new ConnectionFactory();
f.setHost("wht6.cn");
f.setPort(5672);
f.setUsername("admin");
f.setPassword("admin");
Channel channel = f.newConnection().createChannel();
//1.创建随机队列 2.创建交换机 3.绑定
String queue = UUID.randomUUID().toString();
channel.queueDeclare(queue, false, true, true, null);
channel.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
//对fanout交换机,第三个参数无效
channel.queueBind(queue, "logs", "");
//接收处理消息
DeliverCallback deliverCallback= (consumerTag,message)->{
String s = new String(message.getBody());
System.out.println("收到:"+s);
};
CancelCallback cancelCallback=consumerTag -> {};
channel.basicConsume(queue, true, deliverCallback, cancelCallback);
}
}
路由模式(让消费者有选择的挑选想要的信息)
交换机类型是直连
生产者发送消息
package m4;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//连接
ConnectionFactory f = new ConnectionFactory();
f.setHost("192.168.64.140");
f.setPort(5672);
f.setUsername("admin");
f.setPassword("admin");
f.setVirtualHost("hrj");
Channel channel = f.newConnection().createChannel();
//创建Direct交换机:direct_logs
channel.exchangeDeclare("direct_logs", BuiltinExchangeType.DIRECT);
//发送信息,携带路由关键词
while (true){
System.out.println("输入消息");
String s = new Scanner(System.in).nextLine();
System.out.println("输入路由键");
String k = new Scanner(System.in).nextLine();
/**
* 第二个参数是路由关键词
* 在简单模式在工作模式中,使用的默认交换机自动使用队列名做绑定
*
* */
channel.basicPublish("direct_logs", k, null, s.getBytes());
}
}
}
消费者接收消息
package m4;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args)throws IOException, TimeoutException {
//连接
ConnectionFactory f = new ConnectionFactory();
f.setHost("192.168.64.140");
f.setPort(5672);
f.setUsername("admin");
f.setPassword("admin");
f.setVirtualHost("hrj");
Channel channel = f.newConnection().createChannel();
//1.创建随机队列 2.创建交换机 3.绑定,设置绑定键
String queue = UUID.randomUUID().toString();
channel.queueDeclare(queue, false, true, true, null);
channel.exchangeDeclare("direct_logs", BuiltinExchangeType.DIRECT);
System.out.println("输入绑定键,用空格隔开:");
String s1 = new Scanner(System.in).nextLine();
String[] split = s1.split("\\s+");// \s:空白字符 +:一到多个
for (String k:split) {
channel.queueBind(queue, "direct_logs", k);
}
//从队列接收,处理消息
DeliverCallback deliverCallback=(consumerTag,message)->{
String msg = new String(message.getBody());
String routingKey = message.getEnvelope().getRoutingKey();
System.out.println(routingKey+"----------"+msg);
};
CancelCallback cancelCallback=consumerTag -> {};
channel.basicConsume(queue, true, deliverCallback, cancelCallback);
}
}
主题模式
生产者发送消息
package m5;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//连接
ConnectionFactory f = new ConnectionFactory();
f.setHost("192.168.64.140");
f.setPort(5672);
f.setUsername("admin");
f.setPassword("admin");
f.setVirtualHost("hrj");
Channel channel = f.newConnection().createChannel();
//创建Direct交换机:direct_logs
channel.exchangeDeclare("topic_logs", BuiltinExchangeType.TOPIC);
//发送信息,携带路由关键词
while (true){
System.out.println("输入消息");
String s = new Scanner(System.in).nextLine();
System.out.println("输入路由键");
String k = new Scanner(System.in).nextLine();
/**
* 第二个参数是路由关键词
* 在简单模式在工作模式中,使用的默认交换机自动使用队列名做绑定
*
* */
channel.basicPublish("topic_logs", k, null, s.getBytes());
}
}
}
消费者接收消息
package m5;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args)throws IOException, TimeoutException {
//连接
ConnectionFactory f = new ConnectionFactory();
f.setHost("192.168.64.140");
f.setPort(5672);
f.setUsername("admin");
f.setPassword("admin");
f.setVirtualHost("hrj");
Channel channel = f.newConnection().createChannel();
//1.创建随机队列 2.创建交换机 3.绑定,设置绑定键
String queue = UUID.randomUUID().toString();
channel.queueDeclare(queue, false, true, true, null);
channel.exchangeDeclare("topic_logs", BuiltinExchangeType.TOPIC);
System.out.println("输入绑定键,用空格隔开:");
String s1 = new Scanner(System.in).nextLine();
String[] split = s1.split("\\s+");// \s:空白字符 +:一到多个
for (String k:split) {
channel.queueBind(queue, "topic_logs", k);
}
//从队列接收,处理消息
DeliverCallback deliverCallback=(consumerTag,message)->{
String msg = new String(message.getBody());
String routingKey = message.getEnvelope().getRoutingKey();
System.out.println(routingKey+"----------"+msg);
};
CancelCallback cancelCallback=consumerTag -> {};
channel.basicConsume(queue, true, deliverCallback, cancelCallback);
}
}
RabbitMQ 使用场景
- 流量削峰
- 服务解耦
- 异步调用
配置中心+Bus配置刷新
Bus - 消息总线
辅助完成配置刷新,向消息服务器发送刷新指令,从消息服务器接收指令,执行刷新操作
修改2,3,4,9添加Bus和rabbitmq
- 添加依赖
● Bus
● Rabbitmq
● binder rabbit - yml配置rabbitmq连接
● 09的application.yml
● 2,3,4修改config文件夹的三个文件,提交推送到远程仓库 - 09项目用actuator暴露bus-refresh路径
● actuator依赖
● yml配置:m.e.w.e.i=refresh - 访问:POST http://localhost:6001/actuator/bus-refresh
- 启动项目顺序:先启动05,然后09,然后02、03;然后04,最后06