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