中间件(指令和原理)
2022-07-13 16:14:23 0 举报
AI智能生成
登录查看完整内容
中间件相关
作者其他创作
大纲/内容
运维指令
开发指令
指令
ES
负载均衡
反向代理
作用和介绍
/usr/sbin/nginx:主程序/etc/nginx/:存放Nginx配置文件。在指向域名、安装SSL证书时都在这个目录里/usr/share/nginx/:存放Nginx默认指向的静态网页/var/log/nginx/:存放Nginx访问和错误日志
sudo apt-get install nginx
service nginx restart
ps -A | grep nginx
查看nginx状态
server name 为虚拟服务器的识别路径。因此不同的域名会通过请求头中的HOST字段,匹配到特定的server块,转发到对应的应用服务器中去
server_name的作用
搭建
用于缓存,对同样URL的请求,可以hash到同一台上,这样缓存就有效
万一某节点挂了,会导致会序hash算法失效,缓存访问错位,如何解决?
把所有服务器的ip映射到了一致性hash环
增加虚拟节点,虚拟节点映射真实节点
如何保证平衡性?即一致性hash倾斜的问题
一致性hash
URLhash
保证一个ip只映射到某一台固定的后端,解决回话保持问题
nginx启用iphash算法后,backup不能用
多个web-server之间相互同步session,这样每个web-server之间都包含全部的session
session同步法
服务端存储所有用户的session,内存占用较大,可以将session存储到浏览器cookie中,每个端只要存储一个用户的数据了
客户端存储法
方案一:四层代理hash反向代理层使用用户ip来做hash,以保证同一个ip的请求落在同一个web-server上
方案二:七层代理hash反向代理使用http协议中的某些业务属性来做hash,例如sid,city_id,user_id等,能够更加灵活的实施hash策略,以保证同一个浏览器用户的请求落在同一个web-server上
反向代理hash一致性
将session存储在web-server后端的存储层,数据库或者缓存,比如:redis
后端统一存储
分布式session解决方案单点登录
分布式session解决方案与一致性hash
iphash算法
按后端服务器的响应时间来分配请求,响应时间短的优先分配
span style=\
max_fails和fail_timeout的区别
启用backup功能,表示热备,在节点down机后,立刻启动,主节点恢复后切换回原节点
关键属性
负载均衡的几种常用方式
负载均衡算法
nginx为什么这么快
Nginx
Java学习笔记Java_Practice
Go学习笔记GO_Practice
高效开发工具EfficientDevTools
软件基础知识SoftwareBasic
机器学习
数据结构和算法AlgorithmPractice
数据库(原理和指令)
中间件(指令和原理)
踩坑记录(复盘和总结)
工作项目UML图汇总
高可用/高并发/高性能解决方案(3H)
思考
路径跳转
#查看当前用户在哪些组中:确实不在docker组中groups#将当前用户加入docker组中sudo usermod -aG docker huyahui#重新登陆当前用户su - huyahui#验证不用再使用sudo来执行docker命令docker ps
docker安装之后避免每次都需要sudo
安装
docker ps -a
docker ps
docker container ls
docker container ls -all
查看进程
docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地
查找容器版本
不带版本号,默认是最新
docker pull ubuntu
拉取容器
docker run -it 容器名字
docker run -it 容器名字 bash
docker attach 容器名字
此处结尾的 bash 必须加上
docker exec -it 243c32535da7 /bin/bash
docker run -d ubuntu:15.10
docker run -p 8848:8848 容器名称
进入容器
docker stop <容器 ID>
停止一个容器
Error response from daemon: You cannot remove a running container bf08b7f2cd897b5964943134aa6d373e355c286db9b9885b1f60b6e8f82b2b85. Stop the container before attempting removal or force remove
删除容器时,容器必须是停止状态,否则会报如下错误
docker rm -f 1e560fca3906
docker ps -a| grep IDIDIDID
根据ID 查找容器
删除镜像,需要先删除容器
删除容器
docker restart <容器 ID>
重启
docker container prune
清理掉所有处于终止状态的容器
或者反过来
docker cp ID全称:容器文件路径 本地路径
Docker容器和本机之间的文件传输
容器管理
将java项目打包成docker镜像
docker file
1、新建文件夹,把需要的文件copy进去
#基于centos镜像FROM centos#工作目录WORKDIR /home/lj#维护人的信息MAINTAINER ljfirst <ljfirst@mail.ustc.edu.cn>#install jdk and jar包ADD jdk-8u231-linux-x64.tar.gz /usr/java/ADD monitoringalarm-0.0.1-SNAPSHOT.jar /home/lj/#jdk enviromentENV JAVA_HOME=/usr/java/jdk1.8.0_231ENV JRE_HOME=/usr/java/jdk1.8.0_231/jreENV CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/libENV PATH=$JAVA_HOME/bin:$PATH#设置端口EXPOSE 8080#执行命令CMD [\"java\
示例
Dockerfile中ADD的时候,copy的是目录下的文件,而目录本身不复制,所以如果是某个文件夹,需要额外加一层文件夹
2、在该目录下编写docker file
docker build -t myapp . (.不要忘了)
3、运行打包指令
运行的时候需要注意制定端口映射
4、运行镜像
docker 会在当前文件夹下进行镜像打包操作
制作docker
服务的发现与负载的均衡
容器的自动装箱
自动化的容器的恢复
应用的自动发布与应用的回滚,以及与应用相关的配置密文的管理
job 类型任务,Kubernetes 可以去做批量的执行
支持水平的伸缩
k8s功能
API Server:顾名思义是用来处理 API 操作的,Kubernetes 中所有的组件都会和 API Server 进行连接,组件与组件之间一般不进行独立的连接,都依赖于 API Server 进行消息的传送;Controller:是控制器,它用来完成对集群状态的一些管理。比如刚刚我们提到的两个例子之中,第一个自动对容器进行修复、第二个自动进行水平扩张,都是由 Kubernetes 中的 Controller 来进行完成的;Scheduler:是调度器,“调度器”顾名思义就是完成调度的操作,就是我们刚才介绍的第一个例子中,把一个用户提交的 Container,依据它对 CPU、对 memory 请求大小,找一台合适的节点,进行放置;etcd:是一个分布式的一个存储系统,API Server 中所需要的这些原信息都被放置在 etcd 中,etcd 本身是一个高可用系统,通过 etcd 保证整个 Kubernetes 的 Master 组件的高可用性。
架构图
最小调度以及资源单元
Pod
管理 Kubernetes 存储的
Volume
Kubernetes 是通过 Controller,也就是我们刚才提到的控制器去维护 Deployment 中 Pod 的数目,它也会去帮助 Deployment 自动恢复失败的 Pod。比如说我可以定义一个 Deployment,这个 Deployment 里面需要两个 Pod,当一个 Pod 失败的时候,控制器就会监测到,它重新把 Deployment 中的 Pod 数目从一个恢复到两个,通过再去新生成一个 Pod。通过控制器,我们也会帮助完成发布的策略。比如说进行滚动升级,进行重新生成的升级,或者进行版本的回滚
定义一组 Pod 的副本数目、以及这个 Pod 的版本。一般大家用 Deployment 这个抽象来做应用的真正的管理,而 Pod 是组成 Deployment 最小的单元
Deployment
一个 Deployment 可能有两个甚至更多个完全相同的 Pod。对于一个外部的用户来讲,访问哪个 Pod 其实都是一样的,所以它希望做一次负载均衡,在做负载均衡的同时,我只想访问某一个固定的 VIP,也就是 Virtual IP 地址,而不希望得知每一个具体的 Pod 的 IP 地址
提供了一个或者多个 Pod 实例的稳定访问地址
Service
Kubernetes 的每个资源,比如刚才讲的 Pod、Deployment、Service 都属于一个 Namespace,同一个 Namespace 中的资源需要命名的唯一性,不同的 Namespace 中的资源可以重名
集群内部的逻辑隔离的,它包括鉴权、资源管理等
Namespace
核心概念
k8s架构
k8s核心api
Infra container
共享网络
volume 叫做 shared-data,它是属于 Pod level 的
共享存储
pod
概念
禁用swapswapoff -a同时把/etc/fstab包含swap那行记录删掉。关闭防火墙systemctl stop firewalldsystemctl disable firewalld禁用Selinuxapt install selinux-utilssetenforce 0
各主机的主机名及ip配置。同时在每台机器的/etc/hosts配置如下10.2.14.78 wangcf-k8s-m10.2.14.79 wangcf-k8s-n110.2.14.80 wangcf-k8s-n2
系统配置修改
安装前奏
可以拆开执行
apt-get update && apt-get install -y apt-transport-https curl
先安装相关工具
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
添加docker密钥
-y 表示 一路yes
apt-get install docker.io -y
docker安装
docker version
查看docker版本
systemctl enable dockersystemctl start dockersystemctl status docker
启动docker service
安装docker
可以分开执行
先保存一个apt-key.gpg的文件,再通过apt-key add apt-key.gpg来加载
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
获取密钥
源有google、ustc、aliyun的
cat /etc/apt/sources.list.d/kubernetes.list加入以下内容deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
阿里Kubernetes 镜像
添加Kubernetes软件源
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
更新和安装
systemctl enable kubelet
安装kubectl,kubelet,kubeadm
配置master
配置node
Ubuntu16.04安装K8s步骤和踩坑记录
Kubernetes (k8s)
Sidecar模式
Docker(K8s)
安装指令
ps -aux|grep redis
检查Redis服务器系统进程
netstat -nlt|grep 6379
通过启动命令检查Redis服务器状态
redis-server status
通过启动命令检查Redis服务器状态
编辑配置文件,将daemonize参数设置为yes,并使用此配置文件启动这里采用vim打开并编辑配置文件$ sudo vim conf/redis.conf输入/daemonize定位到daemonize no这一行,如果为yes则不需要修改了再输入i或者a转换为输入模式把no改成yes最后输入:wq保存并退出指定此配置文件启动Redis:$ bin/redis-server conf/redis.conf
bin/redis-server conf/redis.conf
守护进程方式在后台启动Redis
/etc/init.d/redis 是安装的地方
/etc/init.d/redis start
/etc/init.d/redis-server stop/etc/init.d/redis-server start/etc/init.d/redis-server restart
从软件仓库中安装的Redis使用init.d脚本启动
redis启动.停止.重启
版本
状态检查和命令行访问
mac使用redis
auth 密码
redis-cli
keys *
set key1 \"hello\"
增加一条字符串记录key1
get key1
打印记录
set key2 1
INCR key2
增加一条数字记录key2
LPUSH key3 a
LPUSH key3 b
增加一条列表记录key3
命令行使用
使用
数据结构
不需要创建/销毁线程,避免上下文切换,无并发资源竞争的问题
单线程机制也避免了不必要的上下文切换和锁机制
单线程
Redis的每一次I/O操作都是基于内存的,非常高效
基于内存
Redis 使用了I/O多路复用,保证了redis在进行I/O操作时依然能处理socket请求,不会在I/O上浪费时间
网络模型
redis为什么这么快
是文件描述符,里面存的是文件句柄
fd_set
IO多路复用的三种机制Select,Poll,Epoll
边缘触发是强触发
epoll的两种工作方式:1.水平触发(LT)2.边缘触发(ET)
1、epoll的核心是事件驱动,触发回调函数,2、事件注册在红黑树上,效率高,无数量限制
红黑树和双链表数据结构,并结合回调机制,造就了epoll的高效
同步值得是:数据已经在内核中ready
异步指的是:数据不光在内核中ready,而且还在用户缓存区ready
异步完成后,内核在IO完成后通知用户线程直接使用即可,而同步完成,还需要把内核数据copy到用户线程缓存区
同步和异步
首先明确CPU不是Redis的瓶颈,瓶颈是网络IO,挑选一个优良的网络IO模型:epoll
Redis是单线程的么?多线程是怎么回事
redis内存模型
redis内存回收
redis内存
原理
1)机器之间网络无法联通2)ip和端口号不正确3)虚拟机中防火墙的原因(可能性较大)4)redis.conf 中bind 127.0.0.1 未用#注释掉
Exception in thread \"main\" redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketT
连接报错
[....] Starting redis-server (via systemctl): redis-server.serviceJob for redis-server.service failed because the control process exited with error code. See \"systemctl status redis-server.service\" and \"journalctl -xe\" for details.
启动报错
错误集锦
Redis
Cache
二进制的安装方式RabbitMQ安装及其基本命令
在安装rabbitmq之前需要安装 socat
rabbitmq的版本需要和 erlang 一致
记安装RabbitMQ中踩坑
安装注意事项
wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
如果提示wget不是一个命令执行yum install wget
下载erlang的仓库
rpm -Uvh erlang-solutions-1.0-1.noarch.rpm
安装erlang仓库
安装erlang的rpm库
yum install erlang
安装erlang
启动erlang,成功# erlErlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:24:24] [async-threads:10] [hipe] [kernel-poll:false]Eshell V7.3 (abort with ^G)1>
验证erlang
erlang
安装erlang依赖
密钥
yum install -y socat
安装socat
*.tar.xz 需要使用xz -d 解压后在 tar -xf 解压
安装xz: yum install xz.x86_64
注意事项
解压rabbitmq-server-generic-unix-3.6.12.tar.xz
./rabbitmq-server start
进入sbin目录启动rabbitMQ
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-3.6.5-1.noarch.rpm
rpm -ivh --nodeps rabbitmq-server-3.6.5-1.noarch.rpm
解决办法
error: Failed dependencies: erlang >= R16B-03 is needed by rabbitmq-server-3.6.5-1.noarch
安装报错
安装RabbitMQ
15672
管控台默认端口号
./rabbitmqctl add_user admin 123456(创建用户)./rabbitmqctl set_user_tags admin administrator(将创建好的用户加入管理员)./rabbitmqctl set_permissions -p \"/\" admin \".\" \".\" \".*\"(授权)./rabbitmq-plugins enable rabbitmq_management 启动RabbitMQ管理页面重启MQ服务、开放5672/15672/25672端口。在浏览器输入ip:15672后出现RabbitMQ管理台。
RabbitMQ配置
先使用 ps -ef | grep rabbitmqkill相应的进程
如果已安装
注意log的位置
注意log的名称
修改log日志,存储到指定地方
lsof -i:5672
查看端口号占有
安装问题
联网安装RabbitMQ教程(tar)
RabbitMQ官网
linux配置安装 RabbitMQ详细教程
一键安装
如果本地装有git,可以不用勾选git
win7、win8 等需要利用 docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/
Docker CLI - 客户端,用来运行 docker 引擎创建镜像和容器。Docker Machine - 可以让你在 Windows 的命令行中运行 docker 引擎命令。Docker Compose - 用来运行 docker-compose 命令。Kitematic - 这是 Docker 的 GUI 版本。Docker QuickStart shell - 这是一个已经配置好Docker的命令行环境。Oracle VM Virtualbox - 虚拟机。
docker toolbox 是一个工具集
它允许的命令实际上是\"C:\\Program Files\\Git\\bin\\bash.exe\" --login -i \"D:\\program\\Docker Toolbox\\start.sh\",这个脚本会检查名字叫default的虚拟机是否存在,如果不存在会调用virtualbox中的create api创建一个
启动Docker Quickstart Terminal
default虚拟机的默认用户名和密码用户名:docker密码: tcuser
docker pull rabbitmq:3.7.7-management
带版本的
docker pull rabbitmq:management
docker images
docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:management
docker上rabbitmq的访问地址
打开浏览器,进入rabbitMQ控制台
安装后检验
安装出错指南
windows上安装docker,再安装rabbitmq
下载erlang
下载RabbitMQ
安装RabbitMQ-Plugins
windows上非docker安装
推荐
ubuntu下RabbitMQ安装与简单使用
首先通过lsof i :15672,或者通过ps -aux |grep 15672|grep -v grep查看是否开启这个15672端口
然后找到rabbitmq的sbin文件,可以全局搜sbin然后找mq下面的这个
使用指令: rabbitmq-plugins enable rabbitmq_management
rabbltmqctl delete_user liujun
rabbitmqctl set_user_tags xxxUser xxxTag
新建用户,在赋权限
开放15672端口,通过浏览器访问rabbitmq控制台
rabbitmq-plugins enable rabbitmq_tracing
RabbitMQ消息追踪插件rabbitmq_tracing
配置
rabbitmqctl status |grep rabbit
查看版本
1.启动rabbitmq:sudo service rabbitmq-server start2.停止rabbitmq:sudo service rabbitmq-server stop3.可以运行命令查看rabbitmq:sudo service rabbitmq-server status4.开启web管理接口sudo rabbitmq-plugins enable rabbitmq_management
查询mq的状态\\开启/关闭mq
开启应用
rabbltmqctl start_app
关闭应用
rabbltmqctl stop_app
节点状态
rabbltmqctl status
给用户赋权限
$sudo rabbitmqctl set_user_tags user_admin administrator
添加用户和密码
rabbltmqctl add_user liujun 123456
查看所有用户
rabbltmqctl list_users
删除用户
rabbltmqctl delete_user liujun
清除用户权限
rabbltmqctl clear_permissions -p vhostpath liujun
修改密码
rabbltmqctl change_password liujun 123456new
rabbltmqctl 用户
添加虚拟主机
rabbltmqctl add_vhost vhostpath
查看虚拟机列表
rabbltmqctl list_vhosts
删除
rabbltmqctl delete vhostpath
vhost
清除队列消息
rabbltmqctl -p vhostpath purge_queue blue
queue
exchange
移除所有数据,需要在rabbltmqctl stop_app之后使用
rabbltmqctl reset
组建集群命令
--ram 指定加入节点的内存模式
--disk 指定加入节点的磁盘模式
rabbltmqctl join_cluster clustrernode --ram
查看集群状态
rabbltmqctl cluster_status
修改集群节点的存储模式
rabbltmqctl change_cluster_node_type disc | ram
忘记节点
--offline 在服务不起动的情况下摘除节点
rabbltmqctl forget_cluster_node --offline
高级操作集群
rabbltmqctl命令
验证
单体搭建
Rabbitmq集群高可用部署详细
队列之间用镜像队列;队列之上用HAproxy:HAproxy之上用VIP;vip可以写在springboot里面
搭建思路
MQ高可用
集群搭建
MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务
接受客户端的连接
server/broker
应用程序和broker之间的连接
connection
消息读写的通道,所有操作在channel中进行
channel
业务调用方
SendMsg(bytes[] msg)
SendCallback()
MQ-client-sender
发送方
MQ-server
zk
db
管理后台web
MQ核心集群
业务接收方
RecvCallback(bytes[] msg)
SendAck()
MQ-client-receiver
接收方
MQ核心架构
虚拟机virtual host
交换机名称
name
重置路由规则的时候记得清空之前的规则
交换机;类型
type
是否持久化
durabilty
最后一个队列消失后,删除该交换机
auto delete
交换机属性
交换机exchange
Queue是用来存储消息的容器,RabbitMQ提供了FIFO(先进先出)的机制,可以缓存消息也可以将消息持久化、临时或者自动删除。
最后一个监听消失后,删除该队列
队列massage queue
将交换机与一个特定的队列绑定起来,且交换机与队列的关系可以是一对一、一对多、多对多
bing中可以含有route key
绑定bing
消息失败回退到那个队列
reply_id
唯一ID
correlationid
消息失效时间
expiration
properties
body
message
massage
实际组成
routingkey对应同名队列
直接交换器(Dirct)
直接绑定交换机和队列,一个交换机对应多个队列
性能最好,速度最快
广播交换器(Fanout)
交换机和队列可以进行模糊匹配
对应routingkey和bindingkey
主题交换器(Topic)
头交换机(Headers)
路由规则
rabbitmq组成
调用方实时依赖执行结果的业务场景,请使用调用,而不是MQ
结论:
MQ只用来传递上游任务执行完成的消息,并不用于传递真正的输入输出数据
调用和消息队列的区别
介绍
交换机和队列持久化,不需要在服务器断电后重新创建队列和交换器了
将他们写入磁盘上的一个持久化日志文件。当发布一条持久性消息到持久交换器上时,Rabbit会在消息提交到日志文件后才发送响应
记住,之后这条消息如果路由到了非持久队列的话,他会自动从持久性日志中移除,并且无法从服务器重启中恢复
一旦你从持久化队列中消费了一条持久性消息的话(并且确认了他),RabbitMQ会在持久化日志中把这条消息标记为等待垃圾收集
RabbitMQ确保持久性消息能从服务器重启中恢复的方式是
使用持久化机制而导致消息吞吐量降低至少10倍的情况并不少见(将RabbitMQ的消息存储于SSD上的话,就可以极大的提升持久化消息通信的性能)
写入磁盘要比存入内存中慢不止一点点,而且会极大的减少RabbitMQ服务器每秒可处理的消息总数
虽然RabbitMQ集群允许你和集群中的任何节点的任一队列进行通信,但是事实上那些队列均匀的分布在各个节点而没有冗余(在集群中任何一个队列都没有备份的拷贝)
持久性消息在RabbitMQ内建集群环境下工作得并不好
性能影响
把他的投递模式选项设置为2(持久)发送到持久化的交换器到达持久化的队列
如果消息想要从Rabbit崩溃中恢复,那么消息必须
防止队列崩溃和恢复(持久化策略)
高可用设计
生产者示例
消费者示例
生产者和消费者demo
Client端使用方式
池化
为了更方便的操作rabbitmq
autostartup设置为true,否则spring容器不会加载
底层是从spring容器中获取exchange、routingkey、binging、queue的@bean
RabbitAdmin
通过bean方式注入
bean写在config里面
SpringAMQP声明
RabbitAdmin的底层具体实现
binging的格式
真正执行工作的是execute
可靠性投递消息
回调监听confirmcallback
返回值确认returncallback
发送消息的方法
RabbitTemplate
为什么可以动态的感知配置变更
simpleMessageListenerContainer
监听的适配器,一个代理
MessageListenerAdapter
MessageConverter
组件
rabbitmq整合Spring-AMQP
rabbitmq整合spring boot
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>这两个依赖不能同时存在,会导致启动报错<dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>3.6.5</version> </dependency>
spring-rabbit和amqp-client不能同时存在,否则会出现class引用错误
Caused by: java.lang.ClassNotFoundException: com.rabbitmq.client.ConfirmCall
问题集锦
Spring整合rabbitmq实践(一):基础Spring整合rabbitmq实践(一):基础Spring整合rabbitmq实践(二):扩展
与spring结合
典型场景一:数据驱动的任务依赖
58同城的很多下游需要关注“用户发布帖子”这个事件,比如招聘用户发布帖子后,招聘业务要奖励58豆,房产用户发布帖子后,房产业务要送2个置顶,二手用户发布帖子后,二手业务要修改用户统计数据。
典型场景二:上游不关心执行结果
典型的是调用离线处理,或者跨公网调用
微信支付,跨公网调用微信的接口,执行时间会比较长,但调用方又非常关注执行结果
典型场景三:上游关注执行结果,但执行时间很长
业务场景
一个单独的交换机和队列
死信队列
消息有存活时间
队列有存活时间
TTL消息
消费段限流
消息的ACK和重回队列
消费段自定义监听
(1)MQ-client将消息发送给MQ-server(此时业务方调用的是API:SendMsg)(2)MQ-server将消息落地,落地后即为发送成功(3)MQ-server将应答发送给MQ-client(此时回调业务方是API:SendCallback)
MQ消息投递上半场
(4)MQ-server将消息发送给MQ-client(此时回调业务方是API:RecvCallback)(5)MQ-client回复应答给MQ-server(此时业务方主动调用API:SendAck)(6)MQ-server收到ack,将之前已经落地的消息删除,完成消息的可靠投递
MQ消息投递下半场
流程
为了降低消息丢失的概率,MQ需要进行超时和重传
MQ上半场的1或者2或者3如果丢失或者超时,MQ-client-sender内的timer会重发消息,直到期望收到3,如果重传N次后还未收到,则SendCallback回调发送失败,需要注意的是,这个过程中MQ-server可能会收到同一条消息的多次重发
上半场的超时与重传
MQ下半场的4或者5或者6如果丢失或者超时,MQ-server内的timer会重发消息,直到收到5并且成功执行6,这个过程可能会重发很多次消息,一般采用指数退避的策略,先隔x秒重发,2x秒重发,4x秒重发,以此类推,需要注意的是,这个过程中MQ-client-receiver也可能会收到同一条消息的多次重发。
下半场的超时与重传
一般采用指数退避的策略,先隔x秒重发,2x秒重发,4x秒重发,以此类推
重传
消息丢失
为了避免步骤2落地重复的消息,对每条消息,MQ系统内部必须生成一个inner-msg-id,作为去重和幂等的依据
消息去重
(1)全局唯一(2)MQ生成,具备业务无关性,对消息发送方和消息接收方屏蔽
内部消息ID的特性
上半场的幂等性设计
(1)对于同一个业务场景,全局唯一(2)由业务消息发送方生成,业务相关,对MQ透明(3)由业务消息消费方负责判重,以保证幂等
最常见的业务ID有:支付ID,订单ID,帖子ID等
biz-id
下半场的幂等性设计
架构幂等性设计
例如可以创建一个包含3600个slot的环形队列(本质是个数组)
环形队列
(1)Cycle-Num:当Current Index第几圈扫描到这个Slot时,执行任务
(2)Task-Function:需要执行的任务指针
图片显示
环上每一个slot是一个Set<Task>
任务集合
两个重要的数据结构
(1)计算这个Task应该放在哪一个slot,现在指向1,3610秒之后,应该是第11格,所以这个Task应该放在第11个slot的Set<Task>中(2)计算这个Task的Cycle-Num,由于环形队列是3600格(每秒移动一格,正好1小时),这个任务是3610秒后执行,所以应该绕3610/3600=1圈之后再执行,于是Cycle-Num=1
即一个取商,一个取余数
实现
高效延时消息设计与实现
消息延时
削峰填谷
保障
MQ消息可靠投递核心流程
图示
消息落库
消息的延迟投递
RabbitMQ的异步调用
消息队列设计
RabbitMQ消息流转
RabbitMQ内存与磁盘管理
顺序消息
mq的使用
原因一般是ConnectionFactory参数设置不对,比如HostName、UserName、Password
$exception {\"None of the specified endpoints were reachable\"} RabbitMQ.Client.Exceptions.BrokerUnreachableException
开发问题集锦
RabbitMQ
kafka
kafka-server-start.sh ../config/server.properties
kafka-server-start.sh -daemon ../config/server.properties
后台启动
使用命令:netstat -anlpt | grep 9092 或者 lsof -i:9092 来查看9092端口占用情况
查看状态
启动
echo stat|nc localhost 2181
zookeeper-server-stop /usr/local/etc/kafka/zookeeper.properties & kafka-server-stop /usr/local/etc/kafka/server.properties
停止
中间件的搭建流程
创建创建主题,该主题包含一个分区,该分区为Leader分区,它没有Follower分区副本。
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic kafkatest
消费者
kafka-console-producer.sh --broker-list localhost:9092 --topic kafkatest
生产者
命令行
关闭zookeeper和kafka,重启服务
先kill 掉zookeeper-server-start.sh -daemon ../config/zookeeper.propertieskafka-server-start.sh -daemon ../config/server.properties
Connection to node -1 (localhost/127.0.0.1:9020) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
1、将server.properties里面的 ip 改成 localhost
2、将启动指令kafka-console-producer.sh --broker-list localhost:9092 --topic kafkatest修改成 localhost
Kafka的使用和错误解决
Error while fetching metadata with correlation id 26 : {kafkatest=LEADER_NOT_AVAILABLE} (org.apache.kafka.clients.NetworkClient)
创建消费者报错
使用问题
问题
Kafka
MQ
下载地址
zkServer.sh start
./zkServer.sh status
看状态
echo stat|nc 127.0.0.1 2181
看版本
版本号
Error: Could not find or load main class org.apache.zookeeper.server.quorum.QuorumPeerMain
zookeeper启动报错出现Starting zookeeper ... FAILED TO START详细解决方案
先看这个里面是否有相关的问题
stat is not executed because it is not in the whitelist.
Zookeeper
Redis安装脚本: installRedis.sh、Redis.conf、Sentinel.conf、VIP绑定脚本Nginx安装脚本: installNginx.sh、makeNginx.sh、nginx.confRabbitMQ及集群的安装脚本: installRabbitMQ.sh 、 installRabbitMQMirrorCluster.shHAProxy安装脚本: installHAProxy.sh、haproxy.cfgKeepalived安装脚本: installKeepalived.sh 、keepalived.conf、 ha_check.shMysql安装脚本 installMysql.sh、my.cnfcentos7的repo样本、刷新yum源的语句: centos7.repo 、yum.sh
常见中间件安装语句
1、通用2、Nginx3、Redis4、Rabbitmq
中间件安装过程中的一些坑
如何实现高并发
如何高效复用网络连接数
类AA实现 了。。。
源码参考
使用时间轮循环。。。。
流程图/架构图
高并发设计
中间件的源码阅读/设计理念/框架结构
命令行使用方式
可视化界面使用方式
幂等
延时
重试
中间件的使用
模版
中间件
分库分表、主从复制、读写分离
Mysql
TiDB Server 负责接收 SQL 请求,处理 SQL 相关的逻辑,并通过 PD 找到存储计算所需数据的 TiKV 地址,与 TiKV 交互获取数据,最终返回结果。 TiDB Server 是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展,可以通过负载均衡组件(如LVS、HAProxy 或 F5)对外提供统一的接入地址。
TiDB Server
Placement Driver (简称 PD) 是整个集群的管理模块,其主要工作有三个: 一是存储集群的元信息(某个 Key 存储在哪个 TiKV 节点);二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);三是分配全局唯一且递增的事务 ID。PD 是一个集群,需要部署奇数个节点,一般线上推荐至少部署 3 个节点
PD Server
TiKV Server 负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value 存储引擎。存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range (从 StartKey 到 EndKey 的左闭右开区间)的数据,每个 TiKV 节点会负责多个 Region 。TiKV 使用 Raft 协议做复制,保持数据的一致性和容灾。副本以 Region 为单位进行管理,不同节点上的多个 Region 构成一个 Raft Group,互为副本。数据在多个 TiKV 之间的负载均衡由 PD 调度,这里也是以 Region 为单位进行调度
TiKV Server
TiDB 集群主要分为三个组件
Tidb
sudo apt install mongodb
sudo systemctl status mongodb sudo systemctl stop mongodb sudo systemctl start mongodb sudo systemctl restart mongodb
sudo systemctl stop mongodb sudo apt purge mongodb sudo apt autoremove
从 Ubuntu 仓库安装 MongoDB 并想要卸载它
Ubuntu 上安装 MongoDB
mongo
使用(创建和编辑)数据库,请输入
安装MongoDB插件
在Idea上配置MongoDB插件并连接MongoDB
Mongodb使用手册
db.users.save({a:\"l\
db.users.insert({a:\"l\
db.users.find({age:18})
db.users.find()
db.users.find({age:18}).count()
db.users.counnt()
use liujundb
show dbs
1、mongodb的配置文件中的bind_ip 默认为127.0.0.1,默认只有本机可以连接。 此时,需要将bind_ip配置为0.0.0.0,表示接受任何IP的连接。
2、防火墙阻止了27017端口。
telnet mongodb的27017端口连接失败
//连接到 mongodb 服务 MongoClient mongoClient = new MongoClient(\"192.168.42.101\
demo
使用mongoTemplate实现多条件加分组查询
SpringBoot整合MongoDB,使用mongoTemplate实现高级查询
java使用mongodb
MongoDB
mongo-express
Ubuntu下安装配置SQLSERVER2017
sqsh -U sa -P Lxxxxxxxx82 -S localhost
sudo apt-get install tdsodbcsudo apt-get install sqshsqsh -U 用户名 -P 密码 -S 服务器地址等一会儿如果出现1> ,就说明连接成功了,可以试着输入如下语句:SELECT @@versiongo注意输入go后才执行语句
ubuntu中连接mssql数据库sqlserver
nacicat连接本地sqlserver数据库
Chinese_PRC_CI_AS
排序规则
SQLServer
ETCD
数据库
中间件指令和原理
0 条评论
回复 删除
下一页