一文读懂Zookeeper与Kafka:从原理到实战部署 - 实践

news/2025/9/25 22:56:58/文章来源:https://www.cnblogs.com/yfceshi/p/19112268

一文读懂Zookeeper与Kafka:从原理到实战部署


在分布式系统的世界里,协调服务与消息队列是保障系统高效、稳定运行的关键组件。Zookeeper作为强大的分布式协调工具,为集群提供了一致性保障;Kafka则凭借高吞吐量的特性,成为大数据实时处理场景中的核心消息中间件。今天,我们就从基础原理出发,一步步深入了解这两个工具,并完成从集群部署到实际应用的全流程实践。

一、Zookeeper:分布式系统的“协调者”

1.1 什么是Zookeeper?

Zookeeper本质是一个分布式协调服务,专门为分布式应用解决协调同步、配置管理、故障恢复等核心问题。它通过类似文件系统的层次化命名空间存储元数据,确保多个节点间的数据一致性,简化分布式系统的管理复杂度。简单来说,Zookeeper就像分布式集群的“指挥官”,让各个节点有序协作,避免混乱。

1.2 核心工作机制:文件系统+通知机制

从设计模式看,Zookeeper基于观察者模式构建,核心可概括为“文件系统+通知机制”:

  • 文件系统:以ZNode为基本数据单元,形成树状结构(类似Linux文件系统),每个ZNode可存储少量数据(默认1MB),并通过唯一路径标识。
  • 通知机制:客户端注册监听ZNode,当ZNode数据或状态变化时,Zookeeper会立即通知所有监听的客户端,触发客户端后续操作(如重新获取配置、更新节点列表)。

举个实际场景:当分布式集群中某台服务器下线时,它在Zookeeper中对应的临时ZNode会自动删除,监听该ZNode的客户端会实时收到通知,从而更新在线服务器列表,保证服务不中断。

1.3 ZNode数据结构:三种核心节点类型

ZNode根据特性可分为三类,不同类型对应不同的应用场景:

1.4 关键应用场景

Zookeeper的功能覆盖了分布式系统的多个核心需求,常见场景包括:

  • 统一命名服务:类似DNS,将难记的IP地址映射为易识别的“域名”,方便服务调用(如用/service/user代替192.168.10.18:8080)。
  • 统一配置管理:将集群所有节点的配置信息存入一个ZNode,节点监听该ZNode。当配置修改时,Zookeeper自动同步到所有节点,避免手动逐个修改(如Kafka集群的配置同步)。
  • 服务器动态上下线:服务器启动时在Zookeeper创建临时ZNode,下线时节点自动删除,客户端通过监听实时获取在线服务器列表。
  • 软负载均衡:记录每台服务器的访问量,让访问量最少的服务器处理新请求,均衡集群压力。

1.5 选举机制:确保集群有且仅有一个“领导者”

Zookeeper集群通过选举机制产生Leader节点(负责处理写请求、同步数据),其余节点为Follower(处理读请求、参与选举),选举分为“第一次启动”和“非第一次启动”两种场景。

第一次启动选举(以5台服务器为例)
  1. 服务器1启动:发起选举,投自己1票,因未达半数(3票),状态保持为“LOOKING”(寻找Leader)。
  2. 服务器2启动:再次发起选举,服务器1和2先投自己,后比较“myid”(服务器唯一标识),服务器1发现服务器2的myid更大,改投服务器2,此时共2票,仍未达半数,状态不变。
  3. 服务器3启动:发起选举,服务器1、2均改投myid更大的服务器3,共3票(超过半数),服务器3当选Leader,状态变为“LEADING”;1、2变为“FOLLOWING”(跟随者)。
  4. 服务器4、5启动:发现已存在Leader,直接变为Follower,无需重新选举。
非第一次启动选举(Leader故障后)

当Leader故障,集群进入重新选举,核心规则按优先级排序:

  1. Epoch优先:Epoch是Leader任期代号,Epoch大的节点直接胜出(确保任期连续性)。
  2. 事务ID(ZXID)优先:Epoch相同时,ZXID(记录节点状态变更的事务ID)大的胜出(ZXID越大,数据越新)。
  3. myid优先:ZXID相同时,myid大的胜出。

1.6 Zookeeper集群部署实战

环境准备

本次部署3台服务器,配置如下:

服务名称IP地址安装组件
zk01192.168.10.18Zookeeper 3.5.7、Kafka 2.7.1、JDK 1.8
zk02192.168.10.21Zookeeper 3.5.7、Kafka 2.7.1、JDK 1.8
zk03192.168.10.22Zookeeper 3.5.7、Kafka 2.7.1、JDK 1.8
部署步骤(以zk01为例,其他节点类似)
  1. 关闭防火墙与安装JDK
# 关闭防火墙并禁用开机启动
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
# 安装JDK 1.8
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
# 验证安装
java -version
  1. 下载并解压Zookeeper
# 进入安装目录
cd /opt
# 下载安装包(官方地址:https://archive.apache.org/dist/zookeeper/)
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
# 解压并移动到指定目录
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz
mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper-3.5.7
  1. 修改配置文件
# 进入配置目录,复制默认配置文件
cd /usr/local/zookeeper-3.5.7/conf/
cp zoo_sample.cfg zoo.cfg
# 编辑配置文件
vim zoo.cfg
# 核心配置(按实际环境修改)
tickTime=2000 # 心跳时间(毫秒)
initLimit=10 # Leader与Follower初始连接超时(10*2000ms)
syncLimit=5 # Leader与Follower同步超时(5*2000ms)
dataDir=/usr/local/zookeeper-3.5.7/data # 数据存储目录(需手动创建)
dataLogDir=/usr/local/zookeeper-3.5.7/logs # 日志目录(需手动创建)
clientPort=2181 # 客户端连接端口
# 添加集群节点信息(server.A=B:C:D,A为myid,B为IP,C为同步端口,D为选举端口)
server.1=192.168.10.18:3188:3288
server.2=192.168.10.21:3188:3288
server.3=192.168.10.22:3188:3288
  1. 配置myid与集群同步
# 在所有节点创建数据和日志目录
mkdir /usr/local/zookeeper-3.5.7/data
mkdir /usr/local/zookeeper-3.5.7/logs
# 按server.A配置myid(zk01写1,zk02写2,zk03写3)
echo 1 > /usr/local/zookeeper-3.5.7/data/myid
# 将配置文件同步到其他节点
scp /usr/local/zookeeper-3.5.7/conf/zoo.cfg 192.168.10.21:/usr/local/zookeeper-3.5.7/conf/
scp /usr/local/zookeeper-3.5.7/conf/zoo.cfg 192.168.10.22:/usr/local/zookeeper-3.5.7/conf/
  1. 启动与验证
# 创建启动脚本(方便管理)
vim /etc/init.d/zookeeper
#!/bin/bash
#chkconfig:2345 20 90
#description:Zookeeper Service Control Script
ZK_HOME='/usr/local/zookeeper-3.5.7'
case $1 in
start)
echo "---------- zookeeper 启动 ----------"
$ZK_HOME/bin/zkServer.sh start
;
;
stop)
echo "---------- zookeeper 停止 ----------"
$ZK_HOME/bin/zkServer.sh stop
;
;
restart)
echo "---------- zookeeper 重启 ----------"
$ZK_HOME/bin/zkServer.sh restart
;
;
status)
echo "---------- zookeeper 状态 ----------"
$ZK_HOME/bin/zkServer.sh status
;
;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
# 赋予脚本执行权限并设置开机自启
chmod +x /etc/init.d/zookeeper
chkconfig --add zookeeper
# 启动Zookeeper(所有节点执行)
service zookeeper start
# 验证状态(查看是否有Leader和Follower)
service zookeeper status

当某节点显示“Mode: leader”,其他节点显示“Mode: follower”时,Zookeeper集群部署成功!

二、Kafka:高吞吐量的消息队列“王者”

2.1 为什么需要Kafka?

在高并发场景中,同步请求容易导致系统阻塞(如大量请求同时访问数据库,引发“too many connection”错误)。而Kafka作为分布式消息队列,通过异步处理缓解系统压力,同时支持流量削峰、应用解耦、消息通讯等核心场景,成为大数据实时处理(如日志收集、实时计算)的首选工具。

对比其他MQ(ActiveMQ、RabbitMQ),Kafka的核心优势在于高吞吐量(每秒处理几十万条消息)和低延迟(最低几毫秒),尤其适合海量数据场景。

2.2 核心概念与架构

Kafka基于发布/订阅模式设计,核心架构包含以下组件:

  • Broker:单台Kafka服务器,一个集群由多个Broker组成,每个Broker可存储多个Topic数据。
  • Topic:消息的分类标识(类似数据库表),生产者向Topic发消息,消费者从Topic收消息。
  • Partition:Topic的物理分区,将Topic拆分到多个Broker,提升并发和扩展性。Kafka仅保证单个Partition内消息有序,多个Partition无序。
  • Replica:Partition的副本,用于数据备份(如副本数为2,意味着1个Leader+1个Follower),确保Broker故障时数据不丢失。
  • Leader/Follower:每个Partition的副本中,Leader负责读写请求,Follower仅同步Leader数据;Leader故障时,从Follower中重新选举。
  • Producer:消息生产者,向Topic推送消息,可指定消息存储的Partition(按Key哈希、轮询等策略)。
  • Consumer/Consumer Group(CG):消费者/消费者组,多个Consumer组成一个CG,共同消费一个Topic的Partition(一个Partition仅被CG内一个Consumer消费,避免重复消费)。
  • Offset:消息的唯一标识,记录消费者的消费位置,消费者可通过调整Offset重新消费历史消息(默认消息保留7天)。

2.3 Kafka与Zookeeper的关系

Kafka依赖Zookeeper存储集群元数据,主要包括:

简单来说,Zookeeper是Kafka集群的“导航仪”,帮助生产者找到消息要发往的Broker,帮助消费者找到要读取的Partition和Offset。

2.4 Kafka集群部署实战

前提条件

已完成Zookeeper集群部署,且所有节点已安装JDK 1.8。

部署步骤(以zk01为例)
  1. 下载并解压Kafka
# 进入安装目录
cd /opt
# 下载安装包(清华源,速度更快)
wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.7.1/kafka_2.13-2.7.1.tgz
# 解压并移动到指定目录
tar zxvf kafka_2.13-2.7.1.tgz
mv kafka_2.13-2.7.1 /usr/local/kafka
  1. 修改配置文件
# 进入配置目录,备份默认配置
cd /usr/local/kafka/config/
cp server.properties{,.bak
}
# 编辑配置文件
vim server.properties
# 核心配置(按实际环境修改)
broker.id=0 # Broker唯一标识(zk01=0,zk02=1,zk03=2)
listeners=PLAINTEXT://192.168.10.18:9092 # 监听IP和端口(每个节点不同)
log.dirs=/usr/local/kafka/logs # 日志/数据存储目录
num.partitions=1 # Topic默认分区数(可按需调整)
log.retention.hours=168 # 消息保留时间(默认7天)
# 连接Zookeeper集群(与Zookeeper配置一致)
zookeeper.connect=192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181
  1. 配置环境变量与启动脚本
# 添加Kafka环境变量
vim /etc/profile
export KAFKA_HOME=/usr/local/kafka
export PATH=$PATH:$KAFKA_HOME/bin
# 生效环境变量
source /etc/profile
# 创建启动脚本
vim /etc/init.d/kafka
#!/bin/bash
#chkconfig:2345 22 88
#description:Kafka Service Control Script
KAFKA_HOME='/usr/local/kafka'
case $1 in
start)
echo "---------- Kafka 启动 ----------"
${KAFKA_HOME}/bin/kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties
;
;
stop)
echo "---------- Kafka 停止 ----------"
${KAFKA_HOME}/bin/kafka-server-stop.sh
;
;
restart)
$0 stop
$0 start
;
;
status)
echo "---------- Kafka 状态 ----------"
count=$(ps -ef | grep kafka | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];
then
echo "kafka is not running"
else
echo "kafka is running"
fi
;
;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
# 赋予权限并设置开机自启
chmod +x /etc/init.d/kafka
chkconfig --add kafka
  1. 同步配置与启动集群
# 将配置同步到其他节点(修改对应broker.id和listeners)
scp /usr/local/kafka/config/server.properties 192.168.10.21:/usr/local/kafka/config/
scp /usr/local/kafka/config/server.properties 192.168.10.22:/usr/local/kafka/config/
# 所有节点启动Kafka
service kafka start
# 验证启动状态
service kafka status

2.5 Kafka命令行操作:实战演练

部署完成后,我们通过命令行操作Kafka,体验消息的生产与消费。

1. 创建Topic
# 创建名为test的Topic,副本数2,分区数3
kafka-topics.sh --create --zookeeper 192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181 --replication-factor 2 --partitions 3 --topic test
2. 查看Topic列表与详情
# 查看所有Topic
kafka-topics.sh --list --zookeeper 192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181
# 查看test Topic详情(含分区、副本、Leader信息)
kafka-topics.sh --describe --zookeeper 192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181 --topic test
3. 生产消息
# 启动生产者,向test Topic发送消息(输入内容后按回车发送)
kafka-console-producer.sh --broker-list 192.168.10.18:9092,192.168.10.21:9092,192.168.10.22:9092 --topic test
4. 消费消息
# 启动消费者,从test Topic消费消息(--from-beginning表示消费历史所有消息)
kafka-console-consumer.sh --bootstrap-server 192.168.10.18:9092,192.168.10.21:9092,192.168.10.22:9092 --topic test --from-beginning
5. 修改分区数与删除Topic
# 将test Topic分区数修改为6(分区数只能增加,不能减少)
kafka-topics.sh --zookeeper 192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181 --alter --topic test --partitions 6
# 删除test Topic(需确保配置中delete.topic.enable=true)
kafka-topics.sh --delete --zookeeper 192.168.10.18:2181,192.168.10.21:2181,192.168.10.22:2181 --topic test

三、进阶实践:Filebeat+Kafka+ELK日志收集

Kafka的经典应用场景之一是日志收集,我们通过“Filebeat(采集日志)+ Kafka(缓冲消息)+ ELK(分析展示)”架构,实现HTTP访问日志的实时收集与可视化。

3.1 架构流程

  1. Filebeat:部署在Web服务器,采集/var/log/httpd/access_log(访问日志)和error_log(错误日志),发送到Kafka的httpd Topic。
  2. Kafka:接收Filebeat的日志消息,缓冲存储,避免日志峰值压垮后续组件。
  3. Logstash:从Kafka拉取日志,解析为结构化数据,发送到Elasticsearch。
  4. Elasticsearch:存储日志数据,提供高效检索。
  5. Kibana:可视化展示日志数据,支持图表分析与日志查询。

3.2 关键配置步骤

1. Filebeat配置(输出到Kafka)
# 编辑Filebeat配置文件
vim /usr/local/filebeat/filebeat.yml
filebeat.prospectors:
- type: log
enabled: true
paths:
- /var/log/httpd/access_log # 访问日志路径
tags: ["access"] # 打标签,用于后续分类
- type: log
enabled: true
paths:
- /var/log/httpd/error_log # 错误日志路径
tags: ["error"]
# 输出到Kafka
output.kafka:
enabled: true
hosts: ["192.168.10.18:9092","192.168.10.21:9092","192.168.10.22:9092"]
topic: "httpd" # 发送到Kafka的httpd Topic
# 启动Filebeat
./filebeat -e -c filebeat.yml
2. Logstash配置(从Kafka拉取,输出到ES)
# 编辑Logstash配置文件
vim /etc/logstash/conf.d/kafka.conf
input {
kafka {
bootstrap_servers =>
"192.168.10.18:9092,192.168.10.21:9092,192.168.10.22:9092"
topics =>
"httpd" # 拉取Kafka的httpd Topic
type =>
"httpd_kafka"
codec =>
"json" # 解析JSON格式日志
auto_offset_reset =>
"latest" # 拉取最新日志
decorate_events =>
true # 附加Kafka属性
}
}
output {
# 访问日志输出到ES的httpd_access-日期索引
if "access" in [tags] {
elasticsearch {
hosts =>
["192.168.10.13:9200"]
index =>
"httpd_access-%{+YYYY.MM.dd}"
}
}
# 错误日志输出到ES的httpd_error-日期索引
if "error" in [tags] {
elasticsearch {
hosts =>
["192.168.10.13:9200"]
index =>
"httpd_error-%{+YYYY.MM.dd}"
}
}
# 控制台打印(调试用)
stdout { codec => rubydebug
}
}
# 启动Logstash
logstash -f kafka.conf
3. Kibana可视化
  1. 访问Kibana地址(如http://192.168.10.13:5601),创建索引模式(如httpd_access-*)。
  2. 进入“Discover”页面,选择创建的索引模式,即可查看实时日志数据,还可通过“Visualize”创建图表(如访问量趋势图、错误类型统计)。

四、总结

Zookeeper与Kafka作为分布式系统的核心组件,各自承担着“协调”与“消息传递”的关键角色。通过本文的学习,我们不仅理解了Zookeeper的选举机制、ZNode数据结构,以及Kafka的高吞吐量原理、分区副本机制,还完成了从集群部署到日志收集实战的全流程操作。

在实际应用中,需根据业务场景调整配置(如Kafka的分区数、副本数,Zookeeper的集群规模),同时结合监控工具(如Prometheus+Grafana)保障集群稳定运行。希望本文能为你在分布式系统的实践路上提供帮助,后续我们还会深入探讨更多进阶特性,敬请期待!

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

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

相关文章

济南网站中企动力彩票网站开发周期

1. 二进制转十进制 按照数据类型分为三种:无符号的二进制整数,有符号的二进制整数和小数二进制数。 1.1 无符号的二进制整数 计算技巧: 从二进制数的右边第一位起,从右往左,先用二进制位置上的数乘以2的相应位数的幂&…

东莞石龙网站建设wordpress最新版怎么变成英文

在游戏中经常会有需要玩家输入一些内容的功能,例如聊天,命名等,这款游戏只有在存档时辉用到命名功能,所以这个过滤也只是一个实验性的功能,我们将使用AC自动机来实现,这是在我们把“csdn”这个词设置为屏蔽…

微网站页面自助建站系统官方版

目录深搜200. 岛屿数量695. 岛屿的最大面积130. 被围绕的区域547. 省份数量417. 太平洋大西洋水流问题回溯广搜111. 二叉树的最小深度752. 打开转盘锁深搜与广搜结合934. 最短的桥深搜 深搜DFS,在搜索到一个新节点时,立即对该新节点进行遍历&#xff0c…

汕头市企业网站建设品牌沈阳公司网站

直接上代码: #初始化用户信息 import randomprint("本比赛参赛英雄为:1老夫子 2典韦 3吕布") name int(input("请您选择出场英雄:"))if name 1:print("您本次选择的英雄为:老夫子——我会让你明白什么…

Java 生态监控体系实战:Prometheus+Grafana+SkyWalking 整合全指南(三) - 教程

Java 生态监控体系实战:Prometheus+Grafana+SkyWalking 整合全指南(三) - 教程2025-09-25 22:47 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overf…

【网络编程】UDP 编程实战:从套接字到聊天室多场景计划构建

【网络编程】UDP 编程实战:从套接字到聊天室多场景计划构建pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

网站重新备案需要多长时间深圳移动网站建设

当Django的内置权限无法满足需求的时候就自己扩展吧~ 背景介绍 overmind项目使用了Django内置的权限系统,Django内置权限系统基于model层做控制,新的model创建后会默认新建三个权限,分别为:add、change、delete,如果给…

做网站的顶部图片怎么打开文件做的网站

目录 一.平台架构与技术特点 二、DeepSeek R1模型介绍与优势 DeepSeek R1 模型简介 DeepSeek R1 模型优势 三.蓝耘智算平台使用DeepSeek教程 展望未来 耘元生代智算云是蓝耘科技推出的一款智算云平台有着以下特点: 一.平台架构与技术特点 基于 Kubernetes 原…

AC自动机在线版本(alert命中报警)

模板洛谷p3311 code: #include<bits/stdc++.h> using namespace std; typedef long long LL; // 常量定义:N为AC自动机状态数上限、数位DP位数上限;mod为答案取模值 const int N=2010,mod=1e9+7;// AC自动机核…

US$79 BMW FEM/BDC Key Programmer Data Desktop Test Platform for FEM/BDC Key and Program ECU Gearbox

BMW FEM/BDC Key Programmer Data Desktop Test Platform for FEM/BDC Key and Program ECU GearboxFEM BDC Module Testing Platform for BMW F20 F30 F35 X5 X6 I3With your FEM/BDC keys, FEM BDC Module Testing P…

week1 homework

C语言代码规范 参考了大公司的标准 1、程序采用缩进风格,每层缩进使用一个制表位(TAB) 2、源程序使用英文书写,尽量不含有中文。 3、左花括号要另起一行,不能跟在上一行的行末; 4、一个变量定义占一行,一个语句…

(南科大深度学习课程笔记)Lecture_2_Mathematical background(数学背景)(上) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

app那个网站开发比较好xp优化大师

Serverless 话题涉及范围极广&#xff0c;几乎包含了代码管理、测试、发布、运维和扩容等与应用生命周期关联的所有环节。在线应用如何不改代码也能迁移到 Serverless 架构&#xff1f;今天&#xff0c;我们来揭秘阿里巴巴成千上万在线应用的Serverless 演进过程。 AWS Lambda …

最牛网站建设是谁装饰公司办公室图片

有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 什么是WebSocket&#xff1f; WebSocket是一种在Web应用程序中实现双向通信的协议。它允许在客户端和服务器之间建立持久…

Java EE ----- Spring MVC (上) - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

秦皇岛网站排名郑州手机网站制作公司哪家好

可以删一下 按住alt按移除可以删掉 选择你要删的那些线 按住alt点移除

浦东做网站如何在社交网站做销售

一、介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张)wxWidgets是一个开源的跨平台的C构架库(framework)&#xff0c;它可以提供GUI(图形用户界面)和其它工具。目前的2.x版本支持所有版本的Windows、带GTK或Motif的Unix和MacOS。相当于大家熟悉的 VC。二、wxWidge…

Windows 10 C盘占用释放 - tfel

C盘又要撑爆...前言 安装的Windows 10 LSTC, 系统盘留了 200G 最近发现可用只剩下50G, 甚至还在减少 排查 使用 SpaceSniffer 看下具体占用 好用,到Windows 10我也觉得它装机必备!!!占用大头 网易云音乐 缓存它默认…

CherryStudio+cpolar:让智能工作流突破组织边界 - 详解

CherryStudio+cpolar:让智能工作流突破组织边界 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…