本页内容包含所有站内用户最新发表的博客.
最新发布
new
nginx
0
200
情景websocket服务端经nginx代理,刷新页面连接正常,大约经过60秒没有发送消息,websocket自动断开连接,控制台打印错误码为1006。
原因在经过nginx代理时,nginx会检测超过60秒(默认)没有活动的套接字,并将其断开连接。
解决方法
一、修改nginx代理超时时间
时间根据实际需求配置,单位秒
proxy_read_timeout86400s;
proxy_send_
java基础
0
192
一、什么是countDownlatchCountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务。
二、方法详解
CountDownLatch(intcount):count为计数器的初始值(一般需要多少个线程执行,count就设为
rabbitmq,springboot
0
291
客户端connection、channels、queues、consumers和系统其它部分自动生成的事件。例如,当一个connection被接受,虚拟主机通过了验证授权,将会发送一个connection_created事件,当一个connection关闭或者由于其它原因失败,将会发送一个connection_closed事件。RabbitMQ提供了一个最小的事件通知机制向RabbitMQ客户端公开。
一、rabbitmq-event-exchange插件rabbitmq-event-exchange是一个消费内部事件并且重新发送到一个topicexchange的插件,因此可以展示事件给客户端应用程序。
为了消费事件,应用程序需要声明一个队列,并绑定到一个系统指定的交换器去消费消息。
插件在默认的虚拟主机上声明了一个topic类型的exchange(交换器)amq.rabbitmq.event。所有的事件都会发送到这个exchange上并绑定一个路由键,比如,exchange.created、binding.deleted。所以你可以只订阅你关注的事件。
交换器的行为类似amq.rabbitmq.log,所有的信息都发布到这里,如果用户没有经过授权,你可以拒绝它们访问。
每个事件都有与之关联的各种属性,它们被转换成AMQP0-9-1数据编码并插入到消息头中。消息的正文始终为空。
启动插件
rabbitmq-pluginsenablerabbitmq_event_exchange
关闭插件
rabbitmq-pluginsdisablerabbitmq_event_exchange
二、事件(Events)RabbitMQ和相关插件通过routingkeys发送事件:
RabbitMQBroker
Queue,ExchangeandBindingevents:
queue.deletedqueue.createdexchange.createdexchange.deletedbinding.createdbinding.deleted
ConnectionandChannelevents:
connection.createdconnection.closedchannel.createdchannel.closed
Consumerevents:
consumer.createdconsumer.deleted
PolicyandParameterevents:
policy.setpolicy.clearedparameter.setparameter.cleared
Virtualhostevents:
vhost.createdvhost.deleted
Userrelatedevents:
user.authentication.successuser.authentication.failureuser.createduser.deleteduser.password.changeduser.password.cleareduser.tags.set
Permissionevents:
permission.createdpermission.deleted
ShovelPlugin
Workerevents:
shovel.worker.statusshovel.worker.removed
FederationPlugin
Linkevents:
federation.link.statusfederation.link.removed
三、集群中如何使用该插件在集群中每个节点都要开启此插件,否则amq.rabbitmq.event交换器不可以正常的被创建。
四、Springboot监听事件
添加rabbitmq配置
spring:
rabbitmq:
host:192.168.1.101
port:5672
username:root
password:root
定义事件监听器RabbitBrokerEventListener
importorg.springframework.amqp.core.Message;
importorg.springframework.amqp.rabbit.connection.ConnectionFactory;
importorg.springframework.amqp.rabbit.core.BrokerEventListener;
importjava.util.Iterator;
importjava.util.Map;
importjava.util.Set;
/**
*@author:Jiajiajia
*@createDate:2023/7/1120:20
*@description:事件监听器
*/
publicclassRabbitBrokerEventListenerextendsBrokerEventListener{
publicRabbitBrokerEventListener(ConnectionFactoryconnectionFactory,String...eventKeys){
super(connectionFactory,eventKeys);
}
@Override
publicvoidonMessage(Messagemessage){
System.out.println("");
System.out.println("--------------------------------");
System.out.println("");
finalStringreceivedRoutingKey=message.getMessageProperties().getReceivedRoutingKey();
System.out.println(receivedRoutingKey);
System.out.println();
finalMapString,Objectheaders=message.getMessageProperties().getHeaders();
finalSetMap.EntryString,Objectentries=headers.entrySet();
finalIteratorMap.EntryString,Objectiterator=entries.iterator();
while(iterator.hasNext()){
//打印header
finalMap.EntryString,Objectnext=iterator.next();
System.out.println(next.getKey()+":"+next.getValue());
}
super.onMessage(message);
}
}
配置监听器RabbitConfig
importorg.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
/**
*@author:Jiajiajia
*@createDate:2023/7/1120:20
*@description:配置事件监听器
*/
@Configuration
publicclassRabbitConfig{
@Bean
publicRabbitBrokerEventListenerbrokerEventListener(AbstractConnectionFactoryconnectionFactory){
//eventKeys是要监听的主题
returnnewRabbitBrokerEventListener(connectionFactory,"user.#","channel.#","queue.#","connection.#","consumer.#");
}
}
redis,springboot
0
248
一、springboot集成redis一般配置pomdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifact
blog
rabbitmq开启http安全认证插件
rabbitmq
0
219
rabbitmq_auth_backend_http插件一、rabbitmq中启用rabbitmq_auth_backend_http插件二、修改配置文件三、开启验证缓存功能一、rabbitmq中启用rabbitmq_auth_backend_http插件命令:rabbitmq-pluginslist##查看插件列表rabbitmq-pluginsenablerabbitmq_auth_backend_http##启用mqtt插件[root@localhostrabbitmq]#rabbitmq-pluginslistListingpluginswithpattern".*"...Configured:E=explicitlyenabled;e=implicitlyenabled|Status:*=runningonrabbit@localhost|/[]rabbitmq_amqp1_03.9.10[]rabbitmq_auth_backend_cache3.9.10[E*]rabbitmq_auth_backend_http3.9.10[]rabbitmq_auth_backend_ldap3.9.10[]rabbitmq_auth_backend_oauth23.9.10[]rabbitmq_auth_mechanism_ssl3.9.10[]rabbitmq_consistent_hash_exchange3.9.10[E*]rabbitmq_delayed_message_exchange3.9.0[E*]rabbitmq_event_exchange3.9.10[]rabbitmq_federation3.9.10......[root@localhostrabbitmq]#rabbitmq-pluginsenablerabbitmq_auth_backend_http......前面带[E*]的代表已启用二、修改配置文件rabbitmq的配置文件默认在/etc/rabbitmq/rabbitmq.conf,如果没有这个文件,则需要自己手动创建这个文件。修改文件vi/etc/rabbitmq/rabbitmq.conf,写入如下内容:#优先使用内部认证auth_backends.1=internal#如果内部认证没有找到用户,则请求http认证auth_backends.2=http#认证请求类型auth_http.http_method=post#认证和授权地址,官方提供了SpringBoot示例auth_http.user_path=http://192.168.1.102:19085/auth/userauth_http.vhost_path=http://192.168.1.102:19085/auth/vhostauth_http.resource_path=http://192.168.1.102:19085/auth/resourceauth_http.topic_path=http://192.168.1.102:19085/auth/topic配置文件中依次配置了auth_backends.1=internal和auth_backends.2=http,意思是优先使用内部认证,如果内部认证没有找到用户,则请求http认证。当然也可以直接配置auth_backends.1=http,这样会直接走http认证,忽略内部认证。(内部认证为rabbitmq服务本地配置的内部用户)auth_http.user_path校验用户登录auth_http.vhost_path验证虚拟主机权限auth_http.resource_path校验使用资源权限(交换机,队列)auth_http.topic_path检查主题是否可以订阅rabbitmq官方给我们提供了一些后端校验的案例:https://github.com/rabbitmq/rabbitmq-auth-backend-http其中启动包含了springboot的案例,和一些其他语言的案例。三、开启验证缓存功能开启http认证后,每次登录或订阅主题登录都会请求http验证权限,过于频繁会影响性能,此时可以开启缓存,在缓存时间内不会重复请求http认证。启用缓存插件[root@localhostrabbitmq]#rabbitmq-pluginsenablerabbitmq_auth_backend_cache修改配置文件#启用cache后,不需要直接指定http方式auth_backends.1=internalauth_backends.2=cache#缓存后端指定为httpauth_cache.cached_backend=http#缓存时间,单位毫秒auth_cache.cache_ttl=10000#认证和授权地址,官方提供了SpringBoot示例auth_http.user_path=http://192.168.1.102:19085/auth/userauth_http.vhost_path=http://192.168.1.102:19085/auth/vhostauth_http.resource_path=http://192.168.1.102:19085/auth/resourceauth_http.topic_path=http://192.168.1.102:19085/auth/topic重启rabbitmq服务servicerabbitmq-serverrestart

blog
for in 和 for of 的区别
javascript,前端
0
252
jsjavascriptforin和forof的区别,forof遍历的原理
一、区别
forin是ES5的语法,forof是ES6的语法forin是无序遍历数组或对象的,也就是随机遍历,不按照顺序来;forof是按照顺序遍历的forin是对key值遍历的,对于对象来说,遍历的是对象的key值,对于数组来说,遍历的是数组的下标;forof是对数组遍历的,不能遍历对象,可以遍历数组,是对数组的每一个元
前端,javascript
0
248
比较点
普通函数
箭头函数
简写
箭头函数如果没有参数,同时函数体的返回值只有一句,则{}和return都可以省略。
this指向
this总是指向调用它的对象,如果作为构造函数,它指向创建的对象实例
箭头函数的this指向的是父级作用域的this,是通过查找作用域链来确定this的值,也就是说看的是上下文的this,指向的是定义它的对象,而不是使用时所在的对象。
this
blog
v-if和v-show的区别
vue
0
267
一.v-show与v-if的共同点在vue中v-show与v-if的作用效果是相同的(不含v-else),都能控制元素在页面是否显示。
当表达式都为false时,都不会占据页面位置当表达式结果为true时,都会占据页面的位置
二、v-show与v-if的区别
控制手段不同编译过程不同编译条件不同
控制手段:v-show隐藏则是为该元素添加css—display:none,dom元素依旧还在。v-
blog
使用openssl生成crt证书
搜索
0
367
官网下载https://www.oomake.com/download/openssl
检查是否安装opensslD:\tmp\sslopensslversion
OpenSSL3.1.014Mar2023(Library:OpenSSL3.1.014Mar2023)
创建证书密钥文件server.keyD:\tmp\sslopensslgenrsa-des3-outserver.key1024
EnterPEMpassphrase:##输入密码
Verifying-EnterPEMpassphrase:##输入确认密码
创建证书申请文件:server.csrD:\tmp\sslopensslreq-new-keyserver.key-outserver.csr
Enterpassphraseforserver.key:##输入前面设置的密码
Youareabouttobeaskedtoenterinformationthatwillbeincorporated
intoyourcertificaterequest.
WhatyouareabouttoenteriswhatiscalledaDistinguishedNameoraDN.
Therearequiteafewfieldsbutyoucanleavesomeblank
Forsomefieldstherewillbeadefaultvalue,
Ifyouenter'.',thefieldwillbeleftblank.
-----
CountryName(2lettercode)[AU]:CN##输入国家代号,中国输入CN
StateorProvinceName(fullname)[Some-State]:BeiJing##省的全名,拼音
LocalityName(eg,city)[]:BeiJing##市的全名,拼音
OrganizationName(eg,company)[InternetWidgitsPtyLtd]:Li##公司英文名
OrganizationalUnitName(eg,section)[]:##可以不输入
CommonName(e.g.serverFQDNorYOURname)[]:##可以不输入
EmailAddress[]:##可以不输入
Pleaseenterthefollowing'extra'attributes
tobesentwithyourcertificaterequest
Achallengepassword[]:##可以不输入
Anoptionalcompanyname[]:##可以不输入
备份一份服务器密钥文件server.key.orgD:\tmp\sslcopyserver.keyserver.key.org
去除文件口令server.keyD:\tmp\sslopensslrsa-inserver.key.org-outserver.key
Enterpassphraseforserver.key.org:##输入前面设置的密码
writingRSAkey
生成证书文件server.crtD:\tmp\sslopensslx509-req-days365-inserver.csr-signkeyserver.key-outserver.crt
Certificaterequestself-signatureok
subject=C=CN,ST=BeiJing,L=BeiJing,O=Li
此时文件夹内:
nginx配置server{
listen443ssl;
server_nametr.test.com;
ssl_certificateD:/tmp/ssl/server.crt;
ssl_certificate_keyD:/tmp/ssl/server.key;
ssl_session_cacheshared:SSL:1m;
ssl_session_timeout5m;
ssl_ciphersHIGH:!aNULL:!MD5;
ssl_prefer_server_cipherson;
location/{
roothtml;
indexindex.htmlindex.htm;
}
error_page500502503504/50x.html;
location=/50x.html{
roothtml;
}
}
数据结构,算法基础
0
282
[数据结构与算法]
一、什么是最小生成树?二、Kruskal算法三、Prim算法一、什么是最小生成树? 在给定一张无向图,如果在它的子图中,任意两个顶点都是互相连通,并且是一个树结构,那么这棵树叫做生成树。当连接顶点之间的图有权重时,权重之和最小的树结构为最小生成树!
在实际中,这种算法的应用非常广泛,比如我们需要在n个城市铺设电缆,则需要n-1条通信线路,那么我们如何铺设可以使得电缆最短呢

blog
并查集 算法分析
数据结构,算法基础
0
270
[数据结构与算法]
一、简介二、算法实现初始化FindUnion三、图示四、算法优化启发式合并路径压缩五、小结一、简介wiki上关于并查集的简介
在计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集(DisjointSets)的合并及查询问题。有一个联合-查找算法(union-findalgorithm)定义了两个用于此数据结构的操作:
Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。Union:将两个子集合并成同一个集合。
并查集主要用于解决动态连通性问题
我们用一个代表来标识一个不交集.通常我们不关心哪个成员作为代表,但是对于属于同一个集合的两个变量,查询应该得到相同的代表。
举个栗子,假如有一个大型的计算机网络,其中有很多台计算机,如果计算机a与计算机b连通,b与c连通,那么a与c连通.对于网络中的两台计算机p,q我们可能有这些操作:判断p,q是否连通find(p)==find(q);在p,q之间建立一条路线使两者连通union(p,q)
通过上面的例子不难看出连通是一种等价关系,它有以下性质:
自反性:p与p是连通的对称性:p与q连通,则q与p连通传递性:p与q连通且q与r连通,则p与r连通
二、算法实现首先我们用一个数组记录所有元素,对于set[i]==k,i表示i个元素,k表示元素所属的集合,通常可以指向或者间接指向集合的代表来表示属于这个集合.当set[i]==i是表明i是一个根节点。set[i]==k可以理解为i,k之间有一条连通的路线,被称为链接。
初始化让所有元素指向自己,表示属于不同的集合,此时集合中每个元素都是一个根节点
privateint[]parent;
publicvoidinit(intn){
parent=newint[n];
for(inti=0;in;i++)
parent[i]=i;
}
Find从x向上查找,直到找到元素的根节点set[i]==i,此根节点就表示这个集合。
publicintfind(intx){
if(parent[x]!=x){
find(parent[x]);
}
returnparent[x];
}
Union把两个不同的点连起来,对于x,y两个点来说,相当与把x,y所在集合合并(传递性),即x,y所在集合所以元素都连通.所以我们可以找到两个集合的代表(根节点),然后把代表合并即可。
publicvoidunion(intx,inty){
//分别查询x、y所在集合的代表
introotX=find(x);
introotY=find(y);
if(rootX==rootY){
//如果存在同一个集合中,则返回
return;
}
//选取rootY作为新集合的代表,把x所在集合合并到y集合
parent[rootX]=rootY;
}
我们在选取谁合并到谁时是随便选取的,实际上合理的选取能够很好地优化算法。
三、图示
1
2
3
4
5
6
7
8
9
10
1
1
1
9
2
5
9
1
9
7
find(6)即为parent[parent[parent[parent[6]]]]==1
find(7)即为parent[parent[7]]==9
union(6,7)
1
2
3
4
5
6
7
8
9
10
9
1
1
9
2
5
9
1
9
7
则rootX=1,rootY=9,即parent[1]=9
1
2
3
4
5
6
7
8
9
10
9
1
1
9
2
5
9
1
9
7
合并完如图:
四、算法优化上面提到合并是随意选取的,那么怎么选取可以优化算法呢.考虑find算法的过程,从低向上查找代表,那么树的高度就决定了find的快慢.所以我们合并时可以考虑把比较矮的树合并到比较高的树上,这样可以有效降低树的高度,从而达到优化算法的目的
启发式合并定义一个数组rank,记录每个节点的树高度,合并时,让较低的树合并到较高的树上,以达到有效降低树高的目的。
privateint[]rank;//记录树的高度
publicvoidunion(intx,inty){
introotX=find(x);
introotY=find(y);
if(rootX==rootY){
return;
}
//比较树高,让较低的树合并到较高的树上
if(rank[rootX]rank[rootY]){
parent[rootX]=rootY;
}elseif(rank[rootX]rank[rootY]){
parent[rootY]=rootX;
}else{
parent[rootY]=rootX;
rank[rootX]++;
}
}
图示:
union(6,7),因为6所在树比7所在树高且大,所以此时parent[9]=1
可以看到相比没有优化的算法,这种合并方式有效地降低了树高
1
2
3
4
5
6
7
8
9
10
1
1
1
9
2
5
9
1
1
7
路径压缩既然把树高降低能优化算法,那么我们能在find中降低树高吗?
我们可以在find中把查找路径上遇到的所有节点都直接链接到根节点,从而实现路径压缩,把树高降低。
代码十分简单,甚至不比上面的复杂.时间复杂度非常接近但是没有达到1
publicintfind(intx){
if(parent[x]!=x){
parent[x]=find(parent[x]);
}
returnparent[x];
}
路径压缩图示
合并6、7两棵树union(6,7)
先会调用find(6),find(7),查找路径上的所以元素都会直接和根节点链接。
1
2
3
4
5
6
7
8
9
10
1
1
1
9
1
1
9
1
9
7
之后parent[1]=9
1
2
3
4
5
6
7
8
9
10
9
1
1
9
1
1
9
1
9
7
五、小结
路径压缩加上启发式合并就是并查集算法的最优解.一般来说用路径压缩算法就足够了,可以不再用启发式合并或者加权

webrtc,srs,音视频
0
642
一、go语言环境搭建srs4.0安装需要go语言环境,所以如果服务器没有配置过go语言环境的话,需要先配置go语言环境。下载安装包官网:https://golang.google.cn/dl/下载和解析:[root@localhostopt]cd/usr/local/[root@localhostlocal]wgethttps://dl.google.com/go/go1.16.5.linux-amd64.tar.gz--no-check-certificate[root@localhostlocal]tar-C/usr/local-xzfgo1.16.5.linux-amd64.tar.gz配置GOROOT和PATH环境变量,在/etc/profile中配置。vi/etc/profile#将环境变量添加到/etc/profile文件末尾。exportGOROOT=/usr/local/goexportPATH=$PATH:$GOROOT/bin:$GOBIN使用source/etc/profile命令使配置文件生效[root@localhostlocal]source/etc/profile查看安装是否成功[root@localhostlocal]goversiongoversiongo1.16.5linux/amd64二、srs源码下载编译我把源码下载到了/opt/文件夹下[root@VM-0-13-centosopt]#gitclone-b4.0releasehttps://gitee.com/ossrs/srs.git编译,注意需要切换到srs/trunk目录:[root@VM-0-13-centossignaling]#cd/opt/srs/trunk[root@VM-0-13-centostrunk]#./configure[root@VM-0-13-centostrunk]#make编译信令服务器,信令服务在srs/trunk/3rdparty/signaling文件夹下[root@VM-0-13-centostrunk]#cd./3rdparty/signaling[root@VM-0-13-centossignaling]#make三、启动srs和信令服务修改rtc配置文件vi/opt/srs/trunk/conf/rtc.conf#WebRTCstreamingconfigforSRS.#@seefull.conffordetailconfig.listen1935;max_connections1000;daemonoff;srs_log_tankfile;srs_log_file/var/log/srs.log;http_server{enabledon;listen8080;dir./objs/nginx/html;}http_api{enabledon;listen1985;}stats{network0;}rtc_server{enabledon;listen8000;#UDPport#@seehttps://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidatecandidatedemo.com;}vhost__defaultVhost__{rtc{enabledon;#@seehttps://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtcrtmp_to_rtcoff;#@seehttps://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmprtc_to_rtmpoff;}http_remux{enabledon;mount[vhost]/[app]/[stream].flv;}}主要修改的配置如下:修改srs_log_tank,日志输出方式,原来是console,改成输出到文件file添加srs_log_file,配置日志文件路径值/var/log/srs.log修改candidate,改成服务端ip或域名启动srs服务,路径/opt/srs/trunk[root@VM-0-13-centostrunk]#./objs/srs-c./conf/rtc.conf&默认端口是:1985启动信令服务:[root@VM-0-13-centostrunk]#nohup./3rdparty/signaling/objs/signaling/var/log/signaling.log&disown默认端口是:1989三、配置nginx代理nginx安装#检查和安装nginx依赖[root@localhostlocal]#yum-yinstallgcczlibzlib-develpcre-developensslopenssl-devel#下载nginx[root@localhostlocal]#wgethttp://nginx.org/download/nginx-1.13.7.tar.gz#解压并进入目录[root@localhostlocal]tar-zxvfnginx-1.13.7.tar.gz[root@localhostnginx-1.13.7]cdnginx-1.13.7/#创建nginx安装目录[root@localhostnginx-1.13.7]mkdir/usr/local/nginx#配置,注意要配置安装ssl模块[root@localhostnginx-1.13.7]./configure--prefix=/usr/local/nginx/--pid-path=/var/run/nginx.pid--with-http_ssl_module#编译和安装[root@localhostnginx-1.13.7]make&&makeinstall[root@localhostnginx-1.13.7]test-d#启动nginx[root@localhostnginx-1.13.7]/usr/local/nginx/sbin/nginx生成ssl证书具体说明参考:https://www.cnblogs.com/pcx105/p/15434332.htmlopensslgenrsa-des3-outserver.key2048#需要输入两次密码,至少四位opensslrsa-inserver.key-outserver.key#需要输入密码opensslreq-new-x509-keyserver.key-outca.crt-days3650opensslreq-new-keyserver.key-outserver.csropensslx509-req-days3650-inserver.csr-CAca.crt-CAkeyserver.key-CAcreateserial-outserver.crtcatserver.keyserver.crtserver.pem修改nginx配置文件server{listen80;##配置httpslisten443ssl;##配置域名server_namewww.demo.com;#charsetkoi8-r;#access_loglogs/host.access.logmain;##配置证书ssl_certificate/usr/local/nginx/conf/ssl/server.pem;ssl_certificate_key/usr/local/nginx/conf/ssl/server.key;ssl_protocolsTLSv1TLSv1.1TLSv1.2;ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;ssl_prefer_server_cipherson;ssl_session_cacheshared:SSL:10m;ssl_session_timeout10m;##srs提供的demo文件路径location/{root/opt/srs/trunk/objs/nginx/html/;}##配置信令服务地址location/sig{proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_read_timeout3600s;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnection"upgrade";proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-NginX-Proxytrue;proxy_passhttp://127.0.0.1:1989/sig;}##配置rtc服务location/rtc{proxy_http_version1.1;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnection"Upgrade";proxy_passhttp://127.0.0.1:1985;}error_page500502503504/50x.html;location=/50x.html{roothtml;}}rtc服务端口是8000/udp,服务器需要放开该端口。firewall-cmd--zone=public--add-port=8000/udp--permanentfirewall-cmd--zone=public--add-port=443/tcp--permanentfirewall-cmd--reload因为webrtc必须在https、或localhost环境下才能访问,所以外网访问需要配置ssl,如果是在外网环境搭建,那么证书可以去阿里云购买,或申请免费的,服务都启动完成之后直接访问域名即可访问webrtc的测试页面。如果是在vm虚拟机上搭建的测试环境,则需要生成证书,证书生成完成后,在nginx上配置即可四、测试访问测试页面:https://192.168.127.128/点击进入srs播放器推流拉流

blog
javascript 计算值所占的百分比
前端
0
364
js计算值所占的百分比:functiongetPercentValue(arr){//求和letsum=0;if(sum=0){for(leti=0;iarr.length;i++){sum+=arr[i];}}//10的2次幂是100,用于计算精度。letdigits=1;//扩大比例100letvotesPerQuota=[];for(leti=0;iarr.length;i++){letva
blog
java计算值所占的百分比
java基础,算法基础
0
361
输入一个整数数组a,输出一个同样长度的数组b表示对应a数组各个位置上的元素值占a数组总值的百分比。publicstaticdouble[]getPercentValue(int[]arr){//求和doublesum=0;if(sum=0){for(inti=0;iarr.length;i++){sum+=arr[i];}}//10的2次幂是100,用于计算精度。doubledigits=1;//
blog
java实现mqtt客户端案例
mqtt协议
0
372
pom依赖dependencygroupIdorg.eclipse.paho/groupIdartifactIdorg.eclipse.paho.client.mqttv3/artifactIdversion1.2.0/version/dependency发布端importorg.eclipse.paho.client.mqttv3.MqttClient;importorg.eclipse.pah
mysql,数据库
0
1044
MySQLgroup_concat()函数用法 在使用groupby对数据进行分组后,如果需要对select的数据项进行字符串拼接,这时就需要用到group_concat()函数。1、基本用法group_concat()完整语法如下:group_concat([DISTINCT]要连接的字段[OrderBY排序字段ASC/DESC][Separator'分隔符']) 通过distinct可以去

blog
redis哨兵模式环境搭建
redis
0
463
介绍 单机版的Redis存在性能瓶颈,Redis通过提高主从复制实现读写分离,提高了了Redis的可用性,另一方便也能实现数据在多个Redis直接的备份。 通过配置Redis的主从复制机制可以提高Redis的可用性,但是一旦主节点出现问题,就需要运维手工切换主从服务节点,即增加了人工成本,且容易出错,而且无法自动化切换,Redis的哨兵机制就能实现自动的主从切换,以及实现对Redis服务的切换。准备 本次测试环境搭建一主两从,三台虚拟机分别是192.168.127.14(主)、192.168.127.101(从)、192.168.127.102(从)。系统环境centos7。 单机搭建redis环境之前的文章中已经提到过,这里不再叙述,参考:http://www.jiajiajia.club/blog/artical/4ngaxn9dyq0t/537,我们在此文章的基础上继续。master主库配置介绍单机安装的时候redis.conf已经配置了如下参数:#绑定的主机,注释掉后允许所有主机登陆#bind127.0.0.1#关闭保护模式protected-modeno#端口,默认为6379port6379#开启后台运行模式daemonizeyes#redis日志文件路径logfile"/usr/local/redis/log/redis.log"#持久化数据文件路径dir"/usr/local/redis/data"#登陆redis数据库的密码认证requirepass"123456"#开启AOF持久化模式appendonlyyes配置哨兵模式时需要在redis.conf配置文件中增加一项配置如下:#哨兵模式中设定主库密码与当前库密码同步,保证从库能够提升为主库masterauth"123456"在/etc/redis/目录下创建sentinel.conf哨兵配置文件,该配置文件和redis.conf在同一个目录(非必须,随意)#关闭保护模式protected-modeno#sentinel默认端口port26379#允许后台运行daemonizeyes#pid文件默认就好pidfile"/var/run/redis-sentinel.pid"#sentinel日志文件logfile"/usr/local/redis/log/sentinel.log"#监听redis主节点是否失效#sentinelmonitormaster-redis-namemaster-redis-ipmaster-redis-portquorum#quorum是一个数字:指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2+1),master才算真正失效。#mymaster这个名字随便取,客户端访问时会用到sentinelmonitormymaster192.168.127.1463792sentinelauth-passmymaster123456sentinelannounce-ip"192.168.127.14"启动master节点的redis和sentinel[root@localhostlog]#/usr/local/bin/redis-server/etc/redis/redis.conf[root@localhostlog]#/usr/local/bin/redis-sentinel/etc/redis/sentinel.conf启动客户端,执行一下命令说明启动成功[root@localhostlog]#/usr/local/bin/redis-cli127.0.0.1:6379auth123456OK127.0.0.1:6379pingPONG127.0.0.1:6379三台服务器都记得开放6379和26379端口firewall-cmd--zone=public--add-port=6379/tcp--permanent&&firewall-cmd--zone=public--add-port=26379/tcp--permanent&&firewall-cmd--reloadslave从库配置 从库的服务安装和配置基本和主库一致,redis.conf和sentinel.conf配置文件可以直接从主库复制过来,做一些修改即可。两台从库的配置是一样的。在redis.conf配置文件中增加一项配置:#配置主从关系slaveof192.168.127.146379修改sentinel.conf配置文件sentinelannounce-ip192.168.127.101这项配置中的ip更换为本机ip,其余配置可不用更改,如果有sentinelmyid配置要将它删除。启动redis和sentinel,方式和启动master节点一样。待master节点和两台slave节点启动完成后,可以查看集群信息[root@localhostlog]#/usr/local/bin/redis-cli127.0.0.1:6379auth123456OK127.0.0.1:6379inforeplication#Replicationrole:master#节点角色,这个是主节点connected_slaves:2slave0:ip=192.168.127.101,port=6379,state=online,offset=172847,lag=1#从节点信息slave1:ip=192.168.127.102,port=6379,state=online,offset=172991,lag=1#从节点信息master_replid:5e9f379fedf9502122ea1bf0667fa135024958dbmaster_replid2:0000000000000000000000000000000000000000master_repl_offset:173278second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:173278127.0.0.1:6379至此,redis的一主两从三哨兵架构搭建完成。springboot配置redis哨兵模式pom文件添加配置dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependencyapplication.yml配置文件server:port:8080spring:redis:database:0password:123456timeout:3000sentinel:#哨兵模式master:mymaster#主服务器所在集群名称nodes:192.168.127.101:26379,192.168.127.102:26379,192.168.127.14:26379lettuce:pool:max-idle:50min-idle:10max-active:100max-wait:1000测试importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.core.ValueOperations;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjavax.annotation.Resource;@RestControllerpublicclassTestController{@ResourceprivateRedisTemplateredisTemplate;@GetMapping("set")publicbooleanset(Stringkey,Stringvalue){finalValueOperationsvalueOperations=redisTemplate.opsForValue();valueOperations.set(key,value);returntrue;}@GetMapping("get")publicObjectget(Stringkey){finalValueOperationsvalueOperations=redisTemplate.opsForValue();finalObjecto=valueOperations.get(key);returno;}} 正常情况下测试,通过接口或者客户端在任意一台服务中添加一个key、value,都会同步到另外两台服务。如果我们手动关闭主节点的redis服务。2023-01-1316:50:59.626INFO9192---[nio-8080-exec-1]o.a.c.c.C.[Tomcat].[localhost].[/]:InitializingSpringDispatcherServlet'dispatcherServlet'2023-01-1316:50:59.626INFO9192---[nio-8080-exec-1]o.s.web.servlet.DispatcherServlet:InitializingServlet'dispatcherServlet'2023-01-1316:50:59.630INFO9192---[nio-8080-exec-1]o.s.web.servlet.DispatcherServlet:Completedinitializationin4ms2023-01-1316:54:10.211INFO9192---[xecutorLoop-1-5]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas/192.168.127.14:63792023-01-1316:54:12.233WARN9192---[ioEventLoop-4-4]i.l.core.protocol.ConnectionWatchdog:Cannotreconnectto[192.168.127.14:6379]:Connectionrefused:nofurtherinformation:/192.168.127.14:63792023-01-1316:54:16.497INFO9192---[ecutorLoop-1-11]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas192.168.127.14:63792023-01-1316:54:18.512WARN9192---[oEventLoop-4-10]i.l.core.protocol.ConnectionWatchdog:Cannotreconnectto[192.168.127.14:6379]:Connectionrefused:nofurtherinformation:/192.168.127.14:63792023-01-1316:54:22.799INFO9192---[xecutorLoop-1-5]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas192.168.127.14:63792023-01-1316:54:24.815WARN9192---[ioEventLoop-4-4]i.l.core.protocol.ConnectionWatchdog:Cannotreconnectto[192.168.127.14:6379]:Connectionrefused:nofurtherinformation:/192.168.127.14:63792023-01-1316:54:29.898INFO9192---[ecutorLoop-1-11]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas192.168.127.14:63792023-01-1316:54:31.910WARN9192---[oEventLoop-4-10]i.l.core.protocol.ConnectionWatchdog:Cannotreconnectto[192.168.127.14:6379]:Connectionrefused:nofurtherinformation:/192.168.127.14:63792023-01-1316:54:37.097INFO9192---[xecutorLoop-1-3]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas192.168.127.14:63792023-01-1316:54:39.116WARN9192---[ioEventLoop-4-2]i.l.core.protocol.ConnectionWatchdog:Cannotreconnectto[192.168.127.14:6379]:Connectionrefused:nofurtherinformation:/192.168.127.14:63792023-01-1316:54:43.298INFO9192---[xecutorLoop-1-5]i.l.core.protocol.ConnectionWatchdog:Reconnecting,lastdestinationwas192.168.127.14:63792023-01-1316:54:43.307INFO9192---[ioEventLoop-4-4]i.l.core.protocol.ReconnectionHandler:Reconnectedto192.168.127.102:6379 主节点(192.168.127.14)关闭后,业务服务进行重连,重连6次失败后连接到从服务器(192.168.127.102)
blog
redis单机安装
redis
0
464
操作系统linuxcentos7准备官网下载安装包:https://redis.io/download/将安装包上传到服务器,解压并进入文件目录[root@localhost~]#tar-zxvfredis-5.0.14.tar.gz&&cdredis-5.0.14[root@localhostredis-5.0.14]#ll总用量284-rw-rw-r--.1rootroot12
blog
git 删除分支
git
0
336
如果只有本地分支存在,则直接删除本地分支即可。如果本地分支和远程分支都存在,则先删除本地分支然后再删除远程分支。删除本地分支在git中,删除本地分支并不会影响远程仓库中的任何分支。删除本地分支的命令:gitbranch-dlocal_branch先列出所有本地分支D:\my_workspace\gitdemogitbranchmaster*test可以看到现在本地有三个分支,当前在test这个分支
rabbitmq,haproxy
0
346
搭建完成rabbitmq镜像集群后,客户端可以根据每个节点的ip进行连接,但是如果将某节点的ip地址写死在代码里,那将失去了扩展性,而且不利于维护。此时需要一个代理服务器,来让三台mq服务平摊压力,实现负载均衡。HAProxy简介HA-HighAvailable高可用,Proxy-代理。HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚

blog
{{data.title}}
{{data.type}}
{{data.createTime}}
{{data.praise}}
{{data.viewNum}}
{{data.description}}
今日推荐
drec
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。