【ELK集群+MQ】通用部署方案以及快速实现MQ发布订阅服务功能

前言:

大概一年多前写过一个部署ELK系列的博客文章,前不久刚好在部署一个ELK的解决方案,我顺便就把一些基础的部分拎出来,再整合成一期文章。大概内容包括:搭建ELK集群,以及写一个简单的MQ服务。

如果需要看一年多之前写的文章,可以详见下列文章链接(例如部署成Windows服务、配置浏览器插件、logstash接收消费者数据等,该篇文章不再重复描述,可以点击下方链接自行参考):

ElasticSearch、head-master、Kibana环境搭建:https://www.cnblogs.com/weskynet/p/14853232.html

给ElasticSearch添加SQL插件和浏览器插件:https://www.cnblogs.com/weskynet/p/14864888.html

使用Logstash通过Rabbitmq接收Serilog日志到ES:https://www.cnblogs.com/weskynet/p/14952649.html

使用nssm工具将ES、Kibana、Logstash或者其他.bat文件部署为Windows后台服务的方法:https://www.cnblogs.com/weskynet/p/14961565.html

安装包目录
将有关环境解压备用。如图:

9fb11fcc109ab22f6b0838a994d643f2.jpeg


说明:集群环境下,使用4 个elasticsearch 数据库。其中三个为master,分别可用于选举主节点、存储数据使用;另外一个为client,仅作为es 的负载均衡使用。如果服务器配置环境太低的情况下,client 也可以不需要,不会产生影响;如果访问会比较频繁,建议可以加上。以下配置操作,均以使用3+1 的集群策略进行配置。


各个环境/安装包说明
Elasticsearch:主要用来存储数据的一个非关系型文档数据库,基于lucene 内核的搜索引擎,可以实现快速搜索数据的目的。一般用来存储日志数据比较常见。
Logstash:用于收集数据的管道, 例如此处用来收集消息队列的数据进行转储到elasticsearch 里面。
Kibana:一个可视化的搜索引擎组件,用来查询elasticsearch 的数据和展示使用。
OpenJDK:非官方版本的JDK 环境,此处使用的是华为镜像下的定制过的open JDK 19 版本。
Elasticsearch-analisis-ik: 一个中文分词工具,用于搜索引擎内搜索词汇时候,可以对词汇进行归集处理,而不至于导致搜索出来的结果是模糊查询。例如:如果没有分词,输入“大佬”进行查询,会把有“大”和“佬”的结果都查询出来。而实际上我们需要查的是“大
佬”这个词。IK 分词的目的就是这个作用。
Elasticsearch-sql: 一款用于提供SQL 语句进行查询的工具。
Sqlsite:一款浏览器插件,用来集成到谷歌内核的浏览器上,可以通过sql 语句进行查询es 的数据集。
Otp_win64_xx : rabbitmq 环境的erlang 语言包环境,安装rabbitmq 服务之前,需要先安装该包
Rabbitmq-server: rabbitmq 安装包


JDK 环境配置


把解压缩的open jdk 的bin 目录,添加到【系统变量】的环境变量Path 里面去。

a1cf9e22d6c3bee96feb9f809eb8522b.jpeg


打开cmd,输入java --version 查看版本,提示版本正确,说明JDK 环境配置OK

f00306a88fcdd5f308505ffd9a4ac37c.jpeg


 RabbitMQ 环境配置
安装Otp 语言包:全部默认下一步到头,简单粗暴。如果有提示确认的,勾选确认即可。

9bddf426b6e550d4fe4405697e41bfa6.jpeg


安装RabbitMQ 服务安装包:同上,直接下一步到底,完成。

a7bf9727dacf3746e885ffc77aba9c1a.jpeg

备注:安装rabbitmq 对应的服务器主机,服务器【主机的名称】和【用户名称】不能有中文字符,不能有中文字符,不能有中文字符,重要的事情说三遍,我年轻时候踩过坑。


配置环境变量。先新增一个ERLANG_HOME,路径是安装erlang的目录:

964337b8260688bd40ff3bc6ea178aeb.jpeg


环境变量的Path 里面新增ERLANG_HOME 的bin 目录:

954019fcf0b36563846f0e1a15cf045d.jpeg

新增RabbitMQ 服务的变量RABBITMQ_SERVER,值是rabbitmq 服务的安装目录:

cd882c0af61ab4a76ffc0b4b3bbff2e4.jpeg

把rabbitmq 的sbin 目录,加入到path 环境变量里面去:

279e2ed279bbe19d63e18adc36c5a1ad.jpeg

打开cmd,输入 rabbitmq-plugins enable rabbitmq_management  进行安装RabbitMQ-Plugins 的插件:

a82ca75a55111bac038acd811f00f7f7.jpeg


设置好以后,打开浏览器,在服务器上输入访问http://127.0.0.1:15672

使用guest 账号进行登录

70b1222677686e05d5892a99909f45fb.jpeg

进去以后,找到Admin 菜单,新增一个用户。此处用户默认为admin,密码默认为admin。
也可以设为其他的,设为其他的。最后点击set 旁边的Admin,再点击左下角的Add User
进行添加一个我们的用户。(不建议使用guest 用户直接做消息队列的处理,可能有安全风
险)

6c4ddce67024610c15af0396abcfc0d5.jpeg


默认添加完成以后,是没有权限的,需要进一步进行添加权限。点击表格下的Name字段,会自动进入到设置权限页面。

4e313fd2a9acd16a82e480e26a6fd222.jpeg

啥也不干,直接点下方第一个按钮【Set permission】即可

cff95e9c1132e87b14709b3d6b3ef305.jpeg


返回Admin 菜单下,可以看到admin 用户的黄色底色已经没有了,并且access 权限也
变成了/

36f3e3605b056788f67327b67b8c773d.jpeg

Elasticsearch 配置文件elasticsearch.yml 说明

【以下内容摘自网络,如果不想科普可以跳过该部分】
cluster.name: elasticsearch
配置的集群名称,默认是elasticsearch,es 服务会通过广播方式自动连接在同一网段下的es服务,通过多播方式进行通信,同一网段下可以有多个集群,通过集群名称这个属性来区分不同的集群。


node.name: "node-01"
当前配置所在机器的节点名,你不设置就默认随机指定一个name 列表中名字,该name 列表在es 的jar 包中config 文件夹里name.txt 文件中,其中有很多作者添加的有趣名字。当创建ES 集群时,保证同一集群中的cluster.name 名称是相同的,node.name 节点名称是不同的;


node.master: true
指定该节点是否有资格被选举成为node(注意这里只是设置成有资格, 不代表该node 一定就是master),默认是true,es 是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。


node.data: true
指定该节点是否存储索引数据,默认为true。


index.number_of_shards: 5
设置默认索引分片个数,默认为5 片。


index.number_of_replicas: 1
设置默认索引副本个数,默认为1 个副本。如果采用默认设置,而你集群只配置了一台机器,那么集群的健康度为yellow,也就是所有的数据都是可用的,但是某些复制没有被分配(健康度可用curl  'localhost:9200/_cat/health?v' 查看, 分为绿色、黄色或红色。绿色代表一切正常,集群功能齐全,黄色意味着所有的数据都是可用的,但是某些复制没有被分配,红色则代表因为某些原因,某些数据不可用)


path.conf: /path/to/conf
设置配置文件的存储路径,默认是es 根目录下的config 文件夹。


path.data: /path/to/data
设置索引数据的存储路径,默认是es 根目录下的data 文件夹,可以设置多个存储路径,用逗号隔开,例:path.data: /path/to/data1,/path/to/data2


path.work: /path/to/work
设置临时文件的存储路径,默认是es 根目录下的work 文件夹。


path.logs: /path/to/logs
设置日志文件的存储路径,默认是es 根目录下的logs 文件夹


path.plugins: /path/to/plugins
设置插件的存放路径,默认是es 根目录下的plugins 文件夹, 插件在es 里面普遍使用,用来增强原系统核心功能。


bootstrap.mlockall: true
设置为true 来锁住内存不进行swapping。因为当jvm 开始swapping 时es 的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM 和ES_MAX_MEM 两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch 的进程可以锁住内存,linux 下启动es 之前可以通过`ulimit -l unlimited`命令设置。


network.bind_host: 192.168.0.1
设置绑定的ip 地址,可以是ipv4 或ipv6 的,默认为0.0.0.0,绑定这台机器的任何一个ip。


network.publish_host: 192.168.0.1
设置其它节点和该节点交互的ip 地址,如果不设置它会自动判断,值必须是个真实的ip 地址。(可以用不配)


network.host: 192.168.0.1
这个参数是用来同时设置bind_host 和publish_host 上面两个二手手机参数。(低版本时配置
0.0.0.0,不然启动会报错。1.7.1 和1.3.1 版本亲测)


transport.tcp.port: 9300
设置节点之间交互的tcp 端口,默认是9300。如我搭建多节点,我的配置分别是9300、9302、9304


transport.tcp.compress: true
设置是否压缩tcp 传输时的数据,默认为false,不压缩。


http.port: 9200
设置对外服务的http 端口,默认为9200。


http.max_content_length: 100mb
设置内容的最大容量,默认100mb


http.enabled: false
是否使用http 协议对外提供服务,默认为true,开启。


gateway.type: local
gateway 的类型,默认为local 即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop 的HDFS,和amazon 的s3 服务器等。


gateway.recover_after_nodes: 1
设置集群中N 个节点启动时进行数据恢复,默认为1。


gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是5 分钟。


gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为2,一旦这N 个节点启动,就会立即进行数据恢复。


cluster.routing.allocation.node_initial_primaries_recoveries: 4
初始化数据恢复时,并发恢复线程的个数,默认为4。


cluster.routing.allocation.node_concurrent_recoveries: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为4。


indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。


indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。


discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它N 个有master 资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)


discovery.zen.ping.timeout: 3s
设置集群中自动发现其它节点时ping 连接超时时间,默认为3 秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。

discovery.zen.ping.multicast.enabled: false
设置是否打开多播发现节点,默认是true。


discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"]
设置集群中master 节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。例如:discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9302","127.0.0.1:9304"] 配置了三个节点


 ES 集群配置文件配置


集群配置,采用3+1 的部署方案,包括3 个可选主节点,以及1 个客户端节点。

其中:

cluster.name 的值保持一致
node.name 的值,可自定义,此处默认可以成为主节点的节点名称为master1 master2和master3

path.data 和path.log 用来存储es 节点存储的数据和自身日志的路径使用。

path.data 的值不能一样,不同的节点,存储的地址需要分开,否则会报错。data 路径用于存放我们发送
给es 的数据所存储的路径位置。


http.port 默认为9200,用于外部访问es 使用;四个节点,端口号此处分别设置为9200、9201、9202、9203。其中9203 端口号用于分配给client 使用。


transport.tcp.port 默认为9300,用于内部集群间通信使用;四个节点,端口号此处分别设置为9300,9301,9302,92303。其中9303 用于client 节点使用。


discovery.seed_hosts 记录的是这四个集群节点的内部通信地址,我本地局域网内的一台服务器为10.1.11.74,所以我此处为了好分辨,就全部写成10.1.11.74 的地址。生产环境下,可以根据实际情况修改为生产环境的ip 地址。


警告:如果es 部署在同一个服务器上,请默认使用127.0.0.1 这个ip,其他ip 可能会受到防火墙限制。例如上面我写的10.1.11.74 的ip,后面就会有集群关连失败的情况。


cluster.initial_master_nodes 此处默认主节点设置为master1,当然也可以设为master2或者3,但是不能是client,因为client 不能当做主节点。


node.master 和node.data,3+1 集群模式下,【master 节点的值全是true】,【client
节点的值全是false】。


以下是我先前做的一个master1 的配置文件截图:

e73abfa0a95de250827408c7eb59fd6a.jpeg

以下是master2 的配置文件截图,可以和以上的master1 的配置文件进行比对查看不同点。master3 节点以此类推。

6303d1211ad5cf5075d2afcb43049acc.jpeg

以下是client 节点的配置文件截图,可以和master 节点进行比较差异点。Client 节点不进行主节点的选举,也不进行存储数据,仅用于负载均衡,用于对3 个主要节点进行压力分解的作用使用。

a5cf77f5a08417796112143aacb6929e.jpeg


Jvm.options 环境配置
Jvm.options 文件在config 文件夹下

6326fb976c17382489c01a92e55104e8.jpeg

该路径下用来配置单个ES 的内存分配规则。最低可以配置512m,最高32g 此处以最高和最低内存使用量都是512m 来配置(公司云服务器配置太低,没办法~)。如果是g 为单位,注意都是小写,并且不带b,例如Xms512m Xmx4g 等等。Xms 代表最低分配内存,Xmx 代表最大分配内存。

4b104316862e0bbeb2b5dc2203a07ef9.jpeg

以此类推,把4 个es 的内存都设置一下。
警告:以上512m 只是因为我本地的局域网内的服务器上的配置比较低,所以在生产环境下,请配置大一点,例如,一台64GB 内存的服务器,以3+1 部署模式进行部署的情况下,最大可以对每个节点
分配(64/2)/5 ≈ 6g 的最大值,其中5 代表的是4 台es 和一台logstash。ELK 的总内存最大
占用建议不要超过服务器总内存的一半,留点面子。


 通过bat 文件启动es 集群进行初始验证


进入到四个es 的根目录下(esxxx/bin),打开cmd,执行elasticsearch.bat 文件:

1be02814a9aca42fd8e9ce561107eb70.jpeg

启动以后,浏览器输入localhost:端口号,例如master1 的端口号是9200,启动成功会有一段简单的提示信息,包括节点名称、集群名称,es 版本等等:

69c64aefdc2ded2f0b52bf373386d213.jpeg

四个es 都启动成功以后,浏览器输入http://localhost:9200/_cat/nodes?v
可以看到集群内部的活动以及主节点信息。当然,上面的ip 和端口号改成任意集群内
的一个节点的地址,都可以查出来。其中master1 为现在的主节点。

d8a94fcbf0e65f7c0ee42b7f129f0a30.jpeg

做个测试,测试主节点宕机以后的效果。(以下内容仅用于测试观看,可以直接跳过)
停止master1 节点,看看情况。

7f9a254b480ed3c4835a93c78f618868.jpeg

刷新一下页面,可以看到少了一个master1,然后master3 被自动选举为主节点。

d1cfd8d71899865258994a9d641495e8.jpeg

重新启动master1 节点,看下效果。如图所示,master1 自动成为了子节点,这个就是集群的魅力,挂了一个一点都不慌。

39705b0ea09528404c3e633d7d55a2f5.jpeg

 集成sql 插件和ik 插件
在所有的es 的plugins 文件夹下,新建两个文件夹,分别是sql 和ik

f3282f1bdd367458df18e8716c0aec25.jpeg


把ik 解压后的内容,全部拷贝到各个es 都ik 文件夹下:
From

03fadaa24c2da6f2456a00fae6afd11e.jpeg

To:

c3521e5a3740cd3a67482b25745fe9f1.jpeg

ik 说明:如果有某个关键词汇查不出来,就可以在ik 分词里面进行新增,例如“老吴”。

新增说明:在ik 的config 目录下,任意找一个词字典,在最后进行添加有关词汇。

75c5d95c394746d900ad651ff8c18eeb.jpeg

把sql 解压后的内容,全部拷贝到各个es 都sql 文件夹下:
From:

0052bbeaafb4ca8f433af2ffaa83763d.jpeg


To:

057dee71785e7ed813f2bf773dc33720.jpeg

添加完成以后,通过bat 启动时候,可以看到有关的加载信息:

79221e57a2c88df6539a908cfd2cc544.jpeg


logstash 的jvm 配置


Logstash 的jvm 配置,同elasticsearch 配置,也需要配置最大内存和最小内存的临界值。
此处写的是2g,我改为了512m(自行根据个人服务器配置进行设置)

b30e4d781bc2f5886759144e2bcefaa1.jpeg


logstash 的config 配置文件设置
config 文件用于指定logstash 使用何种方式进行监听数据流的输入和输出功能,当前使用监听RabbitMQ 的方式来监听日志数据流,然后进行转存到ElasticSearch 数据库上。
以下截图为预设置的配置文件接收端(config 目录下的rabbitmq.conf 文件),预设三个监听数据来源的队列信息。采用direct 模式,并且指定不同的日志内容走不同的队列,例如我之前项目上使用的WCSLog、DeviceLog、ApiLog 等,配置信息可以当做参考。

0ca94e9e0b15a4e0fe8e2fa27797ed31.jpeg

以下截图配置的是每天新增一个索引,分别以sys、device、api 开头。

b029a1d885a10cc0dd48a8778131782e.jpeg

注意事项:RabbitMQ 里面必须已经存在以上的队列以后,才可以启动logstash,否则会启动失败。正确做法是,先启动你的程序,初始化一下或者创建一下MQ 有关的队列信息以后,再启动Logstash。


 Kinaba 配置
打开kibana 根目录下的config 文件夹,下面的kibana.yml 配置文件进行配置。
Kibana 配置比较简单,此处只配置三个地方:

b7ae5aeaf83b37d4595e71fa66ffb53d.jpeg

其中,server.port 是对外开放的端口号,默认是5601,此处改成了15601,防止被人随
意登录。
然后是es.hosts,有多少es 的节点,就都配上去。
还一个是il8n.locale 是默认的语言类型,默认是en 英语,此处我们改为zh-CN 中文。

本公众号文章原文地址是:https://www.cnblogs.com/weskynet/p/16890741.html

如果公众号内显得图片比较小,也可以转场去网上看博客原文。

快速开发MQ生产者和消费者基础服务

新建一个webapi项目进行测试。并添加引用:Wesky.Infrastructure.MQ

c531c85dbeeb4d33da56bed2451df126.png

其中,这个包是我写的一个比较通用的基于DIRECT模式的简易版MQ生产者和消费者基础功能服务,也可以直接拿来做MQ的业务对接开发。

然后,在program.cs里面,添加对WeskyMqService的注册,里面注册了基础的生产者和消费者服务。

06a5f0bc9e828b6d55943a66a421d428.png

 咱新增一个消费者消息消费的方法ConsumeMessage以及有关interface接口,该方法后面用来当作回调函数使用,用来传给MQ消费者,当监听到消息以后,会进入到该方法里面。

2de1c9f88105acda0657f687358229a5.png

 再然后,回到program里面,对刚才新增的方法进行依赖注入的注册;以及在里面做一个简单的MQ队列的配置信息。

3c04deec97151db738970494759a3520.png

 其中,RabbitMqOptions构造函数带有两个参数,分别是

RabbitMqConfiguration:它传入MQ的连接

RabbitMqMessageQueues[]:路由键以及对应的队列名称数组,有多少个队列,数组元素就是多少个一一对应。

以上创建了基础的连接,通过direct模式进行消息订阅和发布;并且创建两个队列,分别是Test1和Test2

再然后,新建一个API控制器,并提供有关依赖注入进行实现的验证。

72c27c280529d2904c08deddd1c271f0.png

为了方便测试,新增两个api接口,用来检测MQ的连接以及消息发布和订阅。

159388aabe95549d40662c56c1e68055.png

 其中,index此处的作用是咱们配置的消息队列的队列数组里面的下标。

连接参数isActive代表是否消费者消费消息,如果不消费消息,那么就可以用来给我们上面的logstash来消费了;如果消费消息,那么消息就会进入到我们刚才创建的ConsumeMessage方法里面去,因为它通过回调函数参数丢进去了:

2f5b7b4e1a1eb206add9c4ca21e15cc7.png

打开MQ面板,可以看到现在是都没有队列存在的。

0d40fd48e4c17a3fd9ee03b31c548789.png

 此时启动程序,先调用连接的API(API里面,包括了生产者连接和消费者连接,平常如果只需要连接一个,也是可以屏蔽其他的,例如与第三方MQ做信息通信的话),再调用发布消息的API,查看效果。咱先做一个不消费(允许消费参数设为false)的例子:

cbdf745314f82125e77c489467a2a2d5.png

 然后再查看MQ面板,可以看到多了两个队列,这两个队列就是代码里面连接以后自动创建的:

54f634a82a9b4c1c4fd3ca995ada624d.png

 调用生产者,发布一条消息,例如发给数组的第一个队列一条消息:

100a4f4a0dd2ee9ddd45c8a4ced168c9.png

 因为不允许消费,所以消息会一直在队列里面没有被消费掉:

dbcb1cd32cc41d63db9fc47ef3a8776d.png

我们先关闭api程序,然后重新做个连接,做成允许消费的,看下效果:

123fb4114b32f208de7f241183b08e30.png

 再切换到MQ面板,可以看到消息立马被消费了:

a7514969685c34397379c926238b5ef7.png

 我们刚才写的一个输出控制台的消费消息的业务方法,此时也被执行了:

0f159d515a0cc93afc25b006d97f4088.png

以上说明MQ的生产者与消费者服务是OK的了。然后就可以与上面的EKL集群进行配合使用,例如你的程序需要通过MQ的方式给Logstash发送消息,那么就可以使用传入不启用MQ客户端消费的功能来实现;如果需要与其他生产者对接,或者需要做MQ消息消费的业务,就可以通过类似方式,写一个回调函数当作参数丢进MQ消费者服务里面去即可。

最后,ELK上面我没做其他的优化,大佬们感兴趣可以自己优化,例如信息的压缩、定时删除等等,这些都可以在Kibana的管理界面里面进行配置。

如果需要以上的环境全套资源、以及后面的MQ的例子,可以扫码关注以下公众号,或者搜索【Dotnet Dancer】关注公众号,发送【ELKQ】即可获取。

eebfcbfcda94e2a83942b4953afbbc6c.jpeg

公众号聊天框内回复【ELKQ】可以获取的工具环境、内容等,见下图:

c2e3923c0bf2c1587b8ca2e6471ef63b.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python容错

#try: except: else: #为什么叫容错呢,先说说错误,这里说的错误并不是因为马虎或者什么原因在脚本中留下的bug,这个不能容掉,所谓容掉就是略过这个错误,要在测试时候发现并修正,需要容错的错误是在脚本执行…

git stash参数介绍

git stash 用于暂存工作区未提交的内容&#xff0c;便于在同时开发多个分支需要切换时保存当前分支进度。 list 语法 git stash list [<options>] &#xff0c;与git log功能类似&#xff0c;列出储藏列表&#xff0c;options 参数可以参考git log的参数 show 语法 git …

多语言报表的改动方法

在定义上传RTF模板的时候&#xff0c;会有一个是否可翻译的选项&#xff0c;选择之后。就能够上传xlf文件作为翻译内容。 对于已经存在的多语言类型报表&#xff0c;稍作改动之后再上传&#xff0c;可能会出现下面现象&#xff1a; 进程出现了“未完毕”的提示 想要改动非常eas…

自定义Cell的流程

1、.h文件 // // 文 件 名:CHBackupGateWayCell.h // // 版权所有:Copyright © 2018 lelight. All rights reserved. // 创 建 者:lelight // 创建日期:2018/12/19. // 文档说明: // 修 改 人: // 修改日期: //#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGINclass…

JS实时监听DOM元素变化 - MutationObserver

使用 MutationObserver API实时监听DOM元素变化 创建 MutationObserver 实列&#xff0c;接受一个用于监听到DOM元素变化的回调函数 const handleListenChange (mutationsList, observer) > {console.log(mutationsList, observer) } const mutationObserver new Mutati…

LightOJ - 1027 A Dangerous Maze —— 期望

题目链接&#xff1a;https://vjudge.net/problem/LightOJ-1027 1027 - A Dangerous MazePDF (English)StatisticsForumTime Limit: 2 second(s)Memory Limit: 32 MBYou are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. The p…

MASA MAUI Plugin (六)集成个推,实现本地消息推送[Android] 篇

背景MAUI的出现&#xff0c;赋予了广大.Net开发者开发多平台应用的能力&#xff0c;MAUI 是Xamarin.Forms演变而来&#xff0c;但是相比Xamarin性能更好&#xff0c;可扩展性更强&#xff0c;结构更简单。但是MAUI对于平台相关的实现并不完整。所以MASA团队开展了一个实验性项目…

第八天

配置文件 Vi /etc/fstab /dev/vg01/lv01 /dir01 ext4 defaults mount -a 扫描 使用交换空间 1.创建分区 2.mkswap /dev/sda创建交换分区 3.swapon /dev/sda启用交换分区 Linux系统启动过程 1、引导程序 BIOS自检 &#xff08;硬件自检&#xff09; 2、G…

iOS 通知中心(NSNotificationCenter)

NSNotificationCenter 在这里第一步和第二步的顺序可以互换&#xff0c;一般楼主我喜欢先在需要发送消息的页面发送消息&#xff0c;然后再在需要监听的页面注册监听。要注意的是不管是通知中心还是KVO都需要在页面销毁之前移除监听。 注册观察者/*** 观察者注册消息通知*…

vue-router和react-router嵌套路由layout配置方案的区别

最近在学习react&#xff0c;在路由这一块有点看不懂&#xff0c;第一感觉是灵活性很大&#xff0c;想怎么来就怎么来&#xff0c;但问题也来了&#xff0c;稍微复杂一点就GG了&#xff0c;不如vue的傻瓜式配置来的方便。 先说一下vue的路由配置方式&#xff0c;目录结构如下&…

微软加更.NET7中文手册,都有哪些新亮点?

11月8号发布了.NET7&#xff0c;从底层性能改进&#xff0c;到上层API升级&#xff0c;让.NET7综合性能再度提升&#xff01;同时发布了最新的C#11&#xff0c;也带来了很多小惊喜。如何快捷学习最新的.NET7和C#11&#xff1f;答案只有一个&#xff0c;微软官方中文文档&#x…

jquery对json的各种遍历

http://caibaojian.com/jquery-each-json.html转载于:https://www.cnblogs.com/pxffly/p/8442448.html

中级工程师之路

前言&#xff1a;之前在问答中问了一个问题 毕业半年感觉没什么进步该怎么办&#xff1f; 这个问题一直让我感觉比计较焦虑。于是在一个关于面试经验的博客中找到了一些灵感。就是通过问题进行学习&#xff0c;对自身的知识体系进行整理和补充。以问题作为切入点&#xff0c;不…

Vue在渲染函数createELement和JSX中使用插槽slot

Vue对于插槽有两个专门的APIvm.$slots和vm.$scopedSlots&#xff0c;分别是普通插槽和作用域插槽&#xff0c;使用JSX语法或渲染函数的时候&#xff0c;定义插槽将使用上述两个API。 渲染函数createElement 普通插槽和作用域插槽在定义上相差不大&#xff0c;但是在使用方法上…

.NET Conf China 2022 第一批讲师阵容大揭秘!整个期待了!

目光看过来2022年12月3-4日一场社区性质的国内规模最大的线上线下.NET Conf 2022技术大会即将盛大开幕目前大会正紧锣密鼓地进行中第一批大咖讲师及主题已确定小编迫不及待想和大家分享分享嘉宾很大咖分享内容很硬核戳戳小手期待ing孔令磊维宏股份 首席架构师 十多年数控领域研…

2017 Material design 第二章第六节《富有创造性的定制方案》

六、富有创造性的定制方案&#xff08;Creative customization&#xff09; 动效可以应用于不同的对象尺寸和不同的环境&#xff0c;这有助于设计美感和功能的统一。 icon的类型系统icons可以有双重功能。 产品icons应该设计得精致、美观。 Icons 系统icons一个系统icon也许存在…

(十四)Java springcloud B2B2C o2o多用户商城 springcloud架构- Spring Cloud构建分布式电子商务平台...

通过Spring Cloud构建PC微信APP云服务的云商平台系统&#xff0c;其中包括B2B、B2C、C2C、O2O、新零售、直播电商等子平台&#xff0c;之前我们讲了很多关于Spring Cloud的概念文章&#xff0c;从本节开始&#xff0c;我们会以分布式微服务电子商务平台为案例&#xff0c;逐步给…

C# 队列(Queue)

概述队列&#xff08;Queue&#xff09;代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时&#xff0c;则使用队列。当您在列表中添加一项&#xff0c;称为入队&#xff0c;当您从列表中移除一项时&#xff0c;称为出队。Queue 类的方法和属性Count 获取 Queu…

vue完全编程方式与react在书写和运用上的异同

在构建html元素时&#xff0c;vue倾向于模板方式&#xff0c;而react则完全使用javascript的编程能力&#xff0c;但vue也具备完全编程的能力&#xff08;与react一样使用JSX和createElement渲染函数&#xff09;。所以&#xff0c;当vue使用完全编程方式时&#xff0c;与react…

Solr 配置文件之schema.xml

schema.xml这个配置文件的根本目的是为了通过配置告诉Solr怎样建立索引。solr的数据结构例如以下&#xff1a;document&#xff1a;一个文档、一条记录 field&#xff1a;域、属性solr通过搜索某个或某些field&#xff0c;返回若干个符合条件的document。或者按搜索的score排序…