OpenStack Telemetry系统架构及实践
1. 概述
早期OpenStack的计量功能由Ceilometer项目负责,后来Ceilometer一分为四,每个项目负责一个方面的工作。不得不说这是OpenStack开发中的一个特色,比如Cinder和Neutron也是从早期的Nova中拆分出来的。
OpenStack Telemetry体系的架构如下:
可以看到其由四个组件构成,包括:
- Gnocchi:时间序列数据库,保存计量数据。
- Panko:事件数据库,保存事件数据。
- Ceilometer:数据采集服务,采集资源使用量相关数据,并推送到Gnocchi;采集操作事件数据,并推送到Panko。
- Aodh:告警服务,基于计量和事件数据提供告警通知功能。
四个组件分工明确,各司其职,使得计量系统结构清晰明了。
另外,早期Ceilometer将原始计量数据保存到MongoDB,性能之差可以说几乎不可用。Gnocchi的出现使计量服务不论是在性能还是空间消耗上都有了质的飞跃,功不可没。也因为Gnocchi的先进性,它已经脱离OpenStack成为了一个独立项目,似有追赶其他时间序列数据库的态势。
2. Gnocchi -- 时间序列数据库服务
Gnocchi接收来自Ceilometer的原始计量数据,进行聚合运算后保存到持久化后端。
2.1 三类存储后端
Gnocchi中保存与资源使用量相关的计量数据,为了提高检索效率,额外将计量数据的元数据信息单独存储。另外由于从原始输入数据到最终存储的聚合数据,需要进行大量计算,为了缓冲输入与处理间的速率,引入缓存后端。因此Gnocchi中涉及三种存储后端:
- 索引后端:存储计量对象和采集项的基础属性,比如对象类型(虚拟机、硬盘、网络)、原始资源uuid等。索引数据量不大,一半用MySQL。
- 聚合数据后端:存储经过聚合计算的计量数据,比如cpu使用率的平均值、最大值、最小值等。推荐用Ceph,可以支持多实例共享数据。
- 传入数据后端:保存来自Ceilometer的原始计量数据。默认与聚合后端一致,推荐使用Redis。
2.2 主要组件
- gnocchi-api:提供数据传入接口,接收原始计量数据,并将它们保存到传入数据后端。同时提供聚合计量数据的查询接口,从聚合数据后端读取计量数据返回给用户。
- gnocchi-metricd:从传入数据后端读取原始计量数据,进行聚合计算,然后将聚合数据保存到聚合数据后端。
2.3 部署配置
2.3.1 配置Keystone
创建gnocchi用户并添加角色:
# openstack user create --domain default --password-prompt gnocchi
# openstack role add --project service --user gnocchi admin
创建gnocchi服务:
# openstack service create --name gnocchi --description "Metric Service" metric
创建endpoints:
# openstack endpoint create --region RegionOne metric public http://controller:8041
# openstack endpoint create --region RegionOne metric internal http://controller:8041
# openstack endpoint create --region RegionOne metric admin http://controller:8041
2.3.2 配置Ceph
将聚合数据保存到Ceph后端,预先在ceph中分配存储池和权限:
# ceph osd pool create gnocchi
# ceph auth get-or-create client.gnocchi mon "allow r" osd "allow rwx pool= gnocchi"
把/etc/ceph/ceph.conf和/etc/ceph/ceph.client.gnocchi.keyring拷贝到Gnocchi节点上。
2.3.3 配置MySQL
使用MySQL保存索引数据,预先创建数据库和用户:
# mysql -u root -p
mysql> CREATE DATABASE gnocchi;
mysql> GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'localhost' \
IDENTIFIED BY 'GNOCCHI_DBPASS';
mysql> GRANT ALL PRIVILEGES ON gnocchi.* TO 'gnocchi'@'%' \
IDENTIFIED BY 'GNOCCHI_DBPASS';
2.3.4 安装Gnocchi
# yum install centos-release-openstack-rocky
# yum install openstack-gnocchi-api openstack-gnocchi-metricd python-gnocchiclient ceph-common
2.3.5 编辑配置
/etc/gnocchi/gnocchi.conf:服务运行参数。
[DEFAULT]
debug = true
verbose = true
log_dir = /var/log/gnocchi
parallel_operations =
coordination_url = redis://controller:6379 [api]
auth_mode = keystone
host = 0.0.0.0
port =
uwsgi_mode = http-socket [keystone_authtoken]
region_name = RegionOne
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000/v3
memcached_servers = controller:
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = gnocchi
password = GNOCCHI_PASS
service_token_roles_required = true [archive_policy]
default_aggregation_methods = mean,min,max,sum,std,count [indexer]
url = mysql+pymysql://gnocchi:GNOCCHI_DBPASS@controller/gnocchi [metricd]
workers =
metric_processing_delay =
greedy = true
metric_reporting_delay =
metric_cleanup_delay = [storage]
#driver = file
driver = ceph
ceph_pool = gnocchi
ceph_username = gnocchi
ceph_keyring = /etc/ceph/ceph.client.gnocchi.keyring
ceph_timeout =
ceph_conffile = /etc/ceph/ceph.conf
file_basepath = /var/lib/gnocchi
file_subdir_len = [cors]
allowed_origin = http://controller:3000
其中[cors]/allowed_origin是grafana的地址,前端直接访问gnocchi获取计量数据,需要配置允许跨域访问。
2.3.6 初始化数据库
# gnocchi-upgrade
2.3.7 启动服务
# systemctl enable openstack-gnocchi-api.service openstack-gnocchi-metricd.service
# systemctl start openstack-gnocchi-api.service openstack-gnocchi-metricd.service
2.4 验证使用
查看归档策略:
# openstack metric archive-policy list
+---------------------+-------------+-----------------------------------------------------------------------+---------------------------------+
| name | back_window | definition | aggregation_methods |
+---------------------+-------------+-----------------------------------------------------------------------+---------------------------------+
| bool | | - points: , granularity: ::, timespan: days, :: | last |
| high | | - points: , granularity: ::, timespan: :: | std, count, min, max, sum, mean |
| | | - points: , granularity: ::, timespan: days, :: | |
| | | - points: , granularity: ::, timespan: days, :: | |
| low | | - points: , granularity: ::, timespan: days, :: | std, count, min, max, sum, mean |
| medium | | - points: , granularity: ::, timespan: days, :: | std, count, min, max, sum, mean |
| | | - points: , granularity: ::, timespan: days, :: | |
+---------------------+-------------+-----------------------------------------------------------------------+---------------------------------+
归档策略指定计量数据的聚合计算方式,包括聚合方法(mean、min、max、sum、std、count),和计量数据的统计时间粒度、数据点数。根据时间粒度和统计点数可以确定计量的时间跨度,根据一个数据点的大小在0.05 bytes~8.04 bytes,就可以确定一个metric需要使用的存储空间大小。Gnocchi内置了bool、low、medium、high四种归档策略。
归档策略的作用单位是计量项(metric)。查看归档策略规则:
# openstack metric archive-policy-rule list
+---------+---------------------+----------------+
| name | archive_policy_name | metric_pattern |
+---------+---------------------+----------------+
| default | low | * |
+---------+---------------------+----------------+
默认规则将所有metric关联到low策略,metric使用通配符匹配。
查看资源列表:
# openstack metric resource list
资源对于OpenStack各个项目中的逻辑资源,比如实例、端口、镜像、卷等。由于还没有对接Ceilometer,所以列表为空。在Ceilometer章节部分可以看到最终结果。
查看metric列表:
# openstack metric metric list
Metric是资源统计的基本单位,一个资源会有多个metrics,比如实例资源有cpu_util、memory.usage、disk.root.size等。
查看计量数据:
# openstack metric measures show {metric_uuid}
Measures就是Gnocchi中最终保存的计量数据,即每个metric的数据点。
3. Panko -- 事件存储服务
Panko接收来自Ceilometer的事件数据,并提供查询接口。
3.1 主要组件
- panko-api: 提供事件数据的插入和查询接口。
3.2 部署配置
3.2.1 配置Keystone
创建panko用户并添加角色:
# openstack user create --domain default --password-prompt panko
# openstack role add --project service --user panko admin
创建panko服务:
# openstack service create event --name panko --description "Panko Service"
创建endpoints:
# openstack endpoint create --region RegionOne event admin http://controller:8977
# openstack endpoint create --region RegionOne event public http://controller:8977
# openstack endpoint create --region RegionOne event internal http://controller:8977
3.2.2 配置MongoDB
使用MongoDB保存事件数据,预先创建数据库和用户:
# mongo
> use panko
> db.createUser({user: "panko",
pwd: "PANKO_DBPASS",
roles: [ "readWrite", "dbAdmin" ]})'
3.2.3 安装Panko
# yum install openstack-panko-api python2-pankoclient
3.2.4 编辑配置
/etc/panko/panko.conf:服务运行参数。
[DEFAULT]
debug = true
log_dir = /var/log/panko [database]
connection = mongodb://panko:PANKO_DBPASS@controller:27017/panko [keystone_authtoken]
region_name = RegionOne
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000/v3
memcached_servers = controller:
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = panko
password = PANKO_PASS
3.2.5 初始化数据库
# panko-dbsync
3.2.6 建立服务文件
Panko安装包内没有包含服务文件,为了便于管理,手动创建panko-api的服务文件:
# cat /usr/lib/systemd/system/openstack-panko-api.service
[Unit]
Description=OpenStack Event API service
After=syslog.target network.target [Service]
Type=simple
User=panko
ExecStart=/usr/bin/panko-api --port -- --logfile /var/log/panko/api.log
Restart=on-failure [Install]
WantedBy=multi-user.target
# systemctl daemon-reload
3.2.7 启动服务
# systemctl enable openstack-panko-api.service
# systemctl start openstack-panko-api.service
3.3 验证使用
查看事件列表:
# openstack event list
由于还没有对接Ceilometer,所以列表为空。
4. Ceilometer -- 数据采集服务
Ceilometer是OpenStack计量体系中的数据采集组件,主要功能有:
- 采集其他OpenStack服务的计量数据,比如虚拟机创建、删除操作等。
- 从消息队列中读取其他服务发送的计量数据,比如虚拟机的CPU使用率、IO等。
- 将采集到的数据发送到后端存储,比如Gnocchi、MongoDB、RabbitMQ等。
4.1 主要组件
- ceilometer-agent-compute:运行在计算节点上,使用libvirt接口采集虚拟机和宿主机的资源消耗数据,并发送到消息队列。
- ceilometer-agent-central:运行在中心节点上,采集服务层面的计量数据,并发送到消息队列。
- ceilometer-agent-notification:运行在中心节点上,从消息队列读取计量数据和事件,并将它们发送到后端存储。
4.2 部署配置
4.2.1 配置Keystone
创建ceilometer用户并添加角色:
# openstack user create --domain default --password-prompt ceilometer
# openstack role add --project service --user ceilometer admin
4.2.2 部署控制节点
1) 安装中心组件
# yum install openstack-ceilometer-notification openstack-ceilometer-central
2) 修改配置
/etc/ceilometer/polling.yaml:配置采集项和采集时间间隔。
/etc/ceilometer/pipeline.yaml:计量数据推送后端,默认是gnocchi://。
/etc/ceilometer/event_pipeline.yaml:事件数据推送后端,默认是gnocchi://,修改为panko://。
/etc/ceilometer/ceilometer.conf:主要配置文件,服务运行参数。
[DEFAULT]
debug = false
auth_strategy = keystone
transport_url = rabbit://openstack:RABBIT_PASS@controller//ceilometer [service_credentials]
auth_type = password
auth_url = http://controller:5000/v3
project_domain_id = default
user_domain_id = default
project_name = service
username = ceilometer
password = CEILOMETER_PASS
interface = internalURL
region_name = RegionOne [notification]
store_events = true
messaging_urls = rabbit://openstack:RABBIT_PASS@controller//glance
messaging_urls = rabbit://openstack:RABBIT_PASS@controller//cinder
messaging_urls = rabbit://openstack:RABBIT_PASS@controller//ceilometer
messaging_urls = rabbit://openstack:RABBIT_PASS@controller//nova
messaging_urls = rabbit://openstack:RABBIT_PASS@controller//neutron
3) 初始化数据库
在Gnocchi上创建资源,要求Gnocchi已运行并在Keystone配置了endpoint。
# ceilometer-upgrade
4) 启动服务
# systemctl enable openstack-ceilometer-notification.service openstack-ceilometer-central.service
# systemctl start openstack-ceilometer-notification.service openstack-ceilometer-central.service
4.2.3 部署计算节点
1) 安装计算节点组件
# yum install openstack-ceilometer-compute
2) 修改配置
/etc/ceilometer/polling.yaml:配置采集项和采集时间间隔。
/etc/ceilometer/ceilometer.conf:主要配置文件,服务运行参数。
[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:RABBIT_PASS@controller//ceilometer [service_credentials]
auth_type = password
auth_url = http://controller:5000/v3
project_domain_id = default
user_domain_id = default
project_name = service
username = ceilometer
password = CEILOMETER_PASS
interface = internalURL
region_name = RegionOne
3) 修改nova配置
/etc/nova/nova.conf中一下计量相关配置:
[DEFAULT]
instance_usage_audit = true
instance_usage_audit_period = hour [notifications]
notify_on_state_change = vm_and_task_state
notification_format = unversioned [oslo_messaging_notifications]
driver = messagingv2
其中要注意notification_format = unversioned,因为目前ceilometer只支持解析unversioned格式的计量消息,所以必须这样配置。
4) 启动服务
# systemctl enable openstack-ceilometer-compute.service
# systemctl start openstack-ceilometer-compute.service
# systemctl restart openstack-nova-compute.service
4.3 验证使用
配置了Ceilometer将计量数据存储到Gnocchi,事件数据存储到Panko,Ceilometer启动后,可以看到相关数据。
查看metric列表:
# openstack metric metric list --limit
+--------------------------------------+---------------------+---------------------------------+-----------+--------------------------------------+
| id | archive_policy/name | name | unit | resource_id |
+--------------------------------------+---------------------+---------------------------------+-----------+--------------------------------------+
| 0144c51d-9be7-42ea-975f-618b3744dc22 | ceilometer-low-rate | disk.device.write.bytes | B | 95f7fed3-6b7b-5f73-bfb7-a0cbf943b0f3 |
| 0189e22c-3e1f-4b8b-b5f1-b73bc13b7084 | ceilometer-low | image.size | B | dd962583-85f6-485f-98cd-b3a790ce3f8e |
| 01a33a01-18b4--afac-1b2d745d3d36 | ceilometer-low | volume.size | GB | dcfdabba-f142-4c97-976f-f75d55c0953a |
| 01c64435-e1d8-47d2-8b2c-8745b2ab5ca7 | ceilometer-low | disk.device.write.bytes.rate | B/s | cddaa528-bc6d-53e9-b205-d24194cc28bd |
| 02100b0a-592a--a479-8ab68f64feb9 | ceilometer-low | disk.root.size | GB | 3c9c995a--4b1a-85bc-46dc6b04b320 |
| 030e15f1-1c94--999d-925bc68a3770 | ceilometer-low-rate | cpu | ns | f89792f8---bfd3-39ea2e1d882b |
| 0313e6c6-86fd---8ba5b32576c3 | ceilometer-low | disk.device.write.requests.rate | request/s | 841054da-180e-5f53-86a2-27faf09dbdd6 |
| 0366ac70-74b8--b2f8-9552d86b7c2d | ceilometer-low | volume.size | GB | a5952eda--4ccd-8c05-9a473b2e0aa5 |
| 040b9167-9e69-4da2--d27fb713d2c5 | ceilometer-low-rate | disk.device.write.requests | request | 76a2dbef--583a--ecb1e222a824 |
| 045655d9-d274-4f61-b4d7-3019732e329d | ceilometer-low | network.incoming.bytes.rate | B/s | d45dcf5a--5b57-9a76-433cbd419fee |
+--------------------------------------+---------------------+---------------------------------+-----------+--------------------------------------+
查看计量数据:
# openstack metric measures show 01c64435-e1d8-47d2-8b2c-8745b2ab5ca7 --start --23T14::
+---------------------------+-------------+---------------+
| timestamp | granularity | value |
+---------------------------+-------------+---------------+
| --23T14::+: | 300.0 | 6362.93010769 |
| --23T14::+: | 300.0 | 7153.82744187 |
+---------------------------+-------------+---------------+
查看事件列表:
# openstack event list --limit
+------------------------+----------------------------+--------------------------------------+-------------+------------------------------------------+-------------+
| event_type | generated | message_id | traits:name | traits:value | traits:type |
+------------------------+----------------------------+--------------------------------------+-------------+------------------------------------------+-------------+
| compute.metrics.update | --25T09::19.990000 | 5cde7191-a485-40ff-ab1d-8609c928bfa6 | service | compute.rocky-cmpt- | string |
| | | | request_id | req-d41eb174-2b06-45df-9cff-c08755878c01 | string |
+------------------------+----------------------------+--------------------------------------+-------------+------------------------------------------+-------------+
5. Aodh -- 告警服务
Aodh根据Gnocchi和Panko中存储的计量和事件数据,提供告警通知功能。
5.1 主要组件
- aodh-api:运行在中心节点上,提供警告CRUD接口。
- aodh-evaluator:运行中心节点上,根据计量数据判断告警是否触发。
- aodh-listener:运行在中心节点上,根据事件数据判断告警是否触发。
- aodh-notifier:运行在中心节点上,当告警被触发时执行预设的通知动作。
5.2 部署配置
5.2.1 配置Keystone
创建aodh用户并添加角色:
# openstack user create --domain default --password-prompt aodh
# openstack role add --project service --user aodh admin
创建aodh服务:
# openstack service create --name aodh --description "Telemetry Alarm" alarming
创建endpoints:
# openstack endpoint create --region RegionOne alarming public http://controller:8042
# openstack endpoint create --region RegionOne alarming internal http://controller:8042
# openstack endpoint create --region RegionOne alarming admin http://controller:8042
5.2.2 配置MySQL
使用MySQL保存索引数据,预先创建数据库和用户:
# mysql -u root -p
mysql> CREATE DATABASE aodh;
mysql> GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'localhost' \
IDENTIFIED BY 'AODH_DBPASS';
mysql> GRANT ALL PRIVILEGES ON aodh.* TO 'aodh'@'%' \
IDENTIFIED BY 'AODH_DBPASS';
5.2.3 安装Aodh
# yum install openstack-aodh-api openstack-aodh-evaluator openstack-aodh-notifier openstack-aodh-listener openstack-aodh-expirer python-aodhclient
5.2.4 编辑配置
/etc/aodh/aodh.conf:服务运行参数。
[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:RABBIT_PASS@controller//aodh [database]
connection = mysql+pymysql://aodh:AODH_DBPASS@controller/aodh [keystone_authtoken]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:
auth_type = password
project_domain_id = default
user_domain_id = default
project_name = service
username = aodh
password = AODH_PASS [service_credentials]
auth_type = password
auth_url = http://controller:5000/v3
project_domain_id = default
user_domain_id = default
project_name = service
username = aodh
password = AODH_PASS
interface = internalURL
region_name = RegionOne
5.2.5 初始化数据库
# aodh-dbsync
5.2.6 修改服务文件
Aodh服务默认监听8000端口,但帮助文档中描述的是8042端口。从Gnocchi监听8041端口来看,Aodh监听8042比较有延续性。修改aodh的服务文件,在启动命令中添加--port 8042参数:
# cat /usr/lib/systemd/system/openstack-aodh-api.service
[Unit]
Description=OpenStack Alarm API service
After=syslog.target network.target [Service]
Type=simple
User=aodh
ExecStart=/usr/bin/aodh-api --port -- --logfile /var/log/aodh/api.log
Restart=on-failure [Install]
WantedBy=multi-user.target
# systemctl daemon-reload
5.2.7. 启动服务
# systemctl enable openstack-aodh-api.service openstack-aodh-evaluator.service openstack-aodh-notifier.service openstack-aodh-listener.service
# systemctl start openstack-aodh-api.service openstack-aodh-evaluator.service openstack-aodh-notifier.service openstack-aodh-listener.service
5.3 验证使用
创建alarm:
# openstack alarm create --name cpu_high \
--type gnocchi_resources_threshold \
--description 'Instance Running HOT' \
--metric cpu_util --threshold \
--comparison-operator ge \
--aggregation-method mean \
--granularity --resource-id 5204dcff-c148-406c-a8ce-dcae8f128e50 \
--resource-type instance --alarm-action 'log://' --ok-action 'log://'
这里设置触发器状态变为alarm和ok时都执行log动作,即记录到aodh-notifier日志中。可以将log://替换为外部告警接口,触发邮件、短信等通知,或者heat、senlin的扩容接口,实现服务自动扩容。
至此OpenStack计量体系的四个组件就部署完成了。
OpenStack Telemetry系统架构及实践的更多相关文章
- 高并发IM系统架构优化实践
互联网+时代,消息量级的大幅上升,消息形式的多元化,给即时通讯云服务平台带来了非常大的挑战.高并发的IM系统背后究竟有着什么样的架构和特性? 以上内容由网易云信首席架构师内部分享材料整理而成 相关阅读 ...
- vivo 容器集群监控系统架构与实践
vivo 互联网服务器团队-YuanPeng 一.概述 从容器技术的推广以及 Kubernetes成为容器调度管理领域的事实标准开始,云原生的理念和技术架构体系逐渐在生产环境中得到了越来越广泛的应用实 ...
- 大型网站系统架构实践(四)http层负载均衡之haproxy实践篇(一)
方案 上篇文章讲到了负载均衡的相关理论知识,这篇文章我打算讲讲实践方法以及实践中遇到的问题 方案:haproxy http层负载均衡 安装一个haproxy服务,两个web服务 haproxy:192 ...
- 大型网站系统架构实践(五)深入探讨web应用高可用方案
从上篇文章到这篇文章,中间用了一段时间准备,主要是想把东西讲透,同时希望大家给与一些批评和建议,这样我才能有所进步,也希望喜欢我文章的朋友,给个赞,这样我才能更有激情,呵呵. 由于本篇要写的内容有点多 ...
- 大型网站系统架构实践(六)深入探讨web应用集群Session保持
原理 在第三,四篇文章中讲到了会话保持的问题,而且还遗留了一个问题,就是会话保持存在单点故障, 当时的方案是cookie插入后缀,即haproxy指负责分发请求,应用服务自行保持用户会话,如果应 用服 ...
- 京东基于Spark的风控系统架构实践和技术细节
京东基于Spark的风控系统架构实践和技术细节 时间 2016-06-02 09:36:32 炼数成金 原文 http://www.dataguru.cn/article-9419-1.html ...
- CC视频CTO栗伟:CDN系统架构及CC视频应用实践
2017 年 11 月9日,CC视频获2.08 亿元C轮融资. EGO 北京分会会员.CC视频CTO栗伟获邀作为 EGO 线上分享第三季嘉宾,与大家交流了CDN系统架构及CC 视频的应用实践. \\ ...
- vivo商城促销系统架构设计与实践-概览篇
一.前言 随着商城业务渠道不断扩展,促销玩法不断增多,原商城v2.0架构已经无法满足不断增加的活动玩法,需要进行促销系统的独立建设,与商城解耦,提供纯粹的商城营销活动玩法支撑能力. 我们将分系列来介绍 ...
- 01 lucene基础 北风网项目培训 Lucene实践课程 系统架构
Lucene在搜索的时候数据源可以是文件系统,数据库,web等等. Lucene的搜索是基于索引,Lucene是基于前面建立的索引之上进行搜索的. 使用Lucene就像使用普通的数据库一样. Luce ...
随机推荐
- [记录]优化Linux 的内核参数来提高服务器并发处理能力
优化Linux 的内核参数来提高服务器并发处理能力PS:在服务器硬件资源额定有限的情况下,最大的压榨服务器的性能,提高服务器的并发处理能力,是很多运维技术人员思考的问题.要提高Linux 系统下的负载 ...
- Eclipse安装STS插件
由于Spring的配置文件较多,基于Eclipse配置也比较复杂.为了提高开发的效率,建议使用STS开发工具开发,或者在Eclipse安装一个STS插件. 在开发者配置bean的class时候能够根据 ...
- sublime 如何安装插件实现高效输入,如何支持markdown 语法,并实时预览
啊,一直想鼓捣markdown的语法,但是配置什么的有点麻烦.不过用起来的话,真心顺手.无需考虑格式与语法点来点去影响效率, 用心去搬砖,用脚修bug 一.初识 Package Control 首先, ...
- .NET Core 3.0之深入源码理解HttpClientFactory(一)
写在前面 创建HttpClient实例的时候,在内部会创建HttpMessageHandler链,我们知道HttpMessageHandler是负责建立连接的抽象处理程序,所以HttpClient的维 ...
- SpringMvc最全的约束——你的感冒清个人总结
SpringMvc最全的约束--你的感冒清个人总结 <?xml version="1.0" encoding="UTF-8"?> <beans ...
- ubuntu root用户 默认密码
ubuntu安装好后,root初始密码(默认密码)不知道,需要设置. 1.先用安装时候的用户登录进入系统 2.输入:sudo passwd 按回车 3.输入新密码,重复输入密码,最后提示passwd ...
- ListView 控件总结
1.ListView类 1.常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示:只有在Details视图该属性才有 ...
- 动态开内存(malloc与calloc)
malloc与calloc 1.函数原型 #include<stdlib.h> void *malloc(unsigned int size); //申请size字节的内存 voi ...
- 从源码看java线程状态
关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...
- MariaDB 修改存储路径后启动失败问题解决
修改 MariaDB 路径到 home 路径下, 执行 systemctl start mariadb 启动MariaDB 时,报错提示: Job for mariadb.service failed ...