在之前的章节中,我们介绍了Ceph集群的组件,一个最小的Ceph集群包括Mon、Mgr和Osd三个部分。为了更好地理解Ceph,我建议在进行部署时采取手动方式,这样方便我们深入了解Ceph的底层。今天我们将进行较长的章节讲解,希望您能耐心阅读完(个人建议可以动手实践一次,效果更佳)。因为Ceph官方文档中对该过程进行了过于简单的描述,许多细节都被隐藏了,然而这些细节对于理解Ceph概念至关重要。

1、网络规划

在部署之前我们先介绍下Ceph的网络,Ceph集群是划分了两种网络(集群网络)Cluster Network、(公共网络)Public Network

  • Cluster Network: 就是Ceph 集群组件内部通信时使用的网络,也称为存储内网。如mon之间相互通信,osd向mon上报其状态信息,主osd向从osd 复制数据等内部操作。

  • Public Network: Ceph集群中用于客户端访问和管理的网络。它是集群与外部世界(客户端、管理员等)通信的主要通道。也称为存储外网。说简单点就是集群外部客户端访问集群内部时的网络。

总结:集群内部访问走Cluster Network ,集群外访问集群内时走Public Network,集群内外怎么区分了? 集群内部组件有 Mon Mgr OSD Mds 等这些内部组件自身通信就是走Cluster Network ,客户或者运维人员使用ceph命令与集群通信,此时走的就是Public Network

思考1OpenStackCeph作为后端存储时,对Ceph的访问是走哪个网络了? 当我们上传镜像到Ceph存储池时走的是哪个网络了?

做过OpenStack运维的小伙伴们,一定少不了镜像制作和上传,如果后端存储是Ceph时,该网络的流量是怎么走了的呢?

#OpenStack 镜像上传命令如下:
openstack image create --container-format bare --disk-format qcow2 \
--public --file /path/to/centos-image.qcow2 centos-image ### 参数说明
--container-format bare 表示容器格式是裸(bare)。
--disk-format qcow2 表示磁盘格式是qcow2。
--public 表示将镜像设置为公共镜像。
--file /path/to/centos-image.qcow2 指定CentOS镜像文件的路径。
centos-image 是你给镜像起的名称。

此时的流量是先是走了OpenStack的管理网,访问了Glance镜像服务,然后Glance作为客户端走Public 网络访问Ceph集群,将数据存储在后端Ceph集群中。(管理网一般是千兆网络,而Ceph 无论是Public 还是 Cluster 网络一般都是万兆及以上高速网络。)

window镜像动辄10GB的大小,上传一个镜像少则几分钟,多则1个小时,那镜像上传的过程可以发现,瓶颈是在OpenStack管理网上,如果我们传文件时不走OpenStack管理网,就能解决该问题。

  1. openstack image create 命令创建一个空镜像并记录其uuid .
  2. 通过rbd命令直接将镜像文件传到Ceph后端,然后给其做快照,并打上快照保护的标记.
  3. 设置glance镜像location url 为rbd的路径。

此过程只是在第一步,创建空镜像时使用了OpenStack管理网,后面所有的操作都是走Public 网络。其效率提高了至少10倍。

思考2: Ceph两个网段是必须的吗?

测试环境中是可以将两个网络合并为一个网络,但是生产环境中是强烈不建议这样使用的。

  1. 从隔离角度来说会造成Public 网络流量过高时,影响集群的稳定性,
  2. 从安全的角度,Public网络是非安全网络,而Cluster网络是安全的网络。

此时我们是一个测试环境就简单规划为一个网络 192.168.200.0/24

2、 Mon 部署

一个Ceph集群至少需要一个Mon和少量OSD,部署一个Mon 需要提前先了解下如下几个概念

  • Unique Identifier: 集群唯一标识符,在集群中显示为fsid, (由于最初的ceph集群主要支持文件系统,所以最初fsid代表文件系统ID,现在ceph集群也支持了块存储和对象存储,但是这个名字确保留下来。文件存储是最先被规划的,相对对象存储和块存储,却是最后生产可用的。)

  • Cluster Name 集群名字,如果不指定默认为ceph,注意如果是多个ceph集群的环境需要指定。

    当一个节点做为客户端要访问两个Ceph集群 cluster1 和 cluster2 时,需要在ceph 命令指定参数

ceph --cluster CLUSTER  cluster name
  • Monitor Name: Mon名字,默认mon使用主机名为自Mon节点的名字,因此需要做好域名解析。

  • Monitor Map:启动初始monitor需要生成monitor map。monitor映射需要fsid,集群的名字以及一个主机名或IP地址。( 在生活中我们去一个陌生地方会先查地图(map),同理mon第一次初始化和查找同伴时也需要Mon Map)

  • Keyring :Ceph 认证密钥环,用于集群身份认证。Cephx认证的不仅有客户端用户(比如某客户端要想执行命令来操作集群,就要有登录Ceph的密钥),也有Ceph集群的服务器,这是一种特殊的用户类型MON/OSD/MDS。也就是说,Monitor、OSD、MDS都需要账号和密码来登录Ceph系统。因此这里的Keyring既有集群内组件的,也有用于管理的Keyring 。(这一点和K8s集群的认证很类似,都是采用双向认证)

了解上述这些是为了能看懂Ceph的配置文件,但是我们在部署时可以不写配置文件,但是在生产环境中强烈建议是手动编写配置文件

2.1 MON 部署前置任务

环境说明:
部署环境 vmware 虚拟机
虚拟机系统 CentOS Linux release 7.9.2009 (Core)
部署ceph版本: 14.2.22 nautilus (stable)
ip 主机名 角色 磁盘
192.168.200.11 mon01 mon mgr osd sdb,sdc,sde,sdf
1 修改主机名,添加hosts 文件解析
hostnamectl set-hostname mon01
echo "192.168.200.11 mon01" >> /etc/hosts 2 关闭防火墙和seliux
systemctl stop firewalld
setenforce 0
getenforce
#Disabled 3 配置ceph 的yum 源,这里使用国内的aliyun的镜像站点 cat > /etc/yum.repos.d/ceph.repo <<EOF
[ceph]
name=ceph
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/x86_64/
gpgcheck=0
EOF 4 检查repo
yum repolist 5 自身免密
ssh-keygen -t rsa #自己的管理IP
ssh-copy-id mon01: 6 安装ceph 包和其依赖包
yum install -y snappy leveldb gdisk python-argparse gperftools-libs ceph

检查安装包

检查ceph客户端的版本

[root@mon01 ~]# ceph -v
ceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable)

【注意】安装了ceph 的基础组件包之后,系统默认在/var/lib/ceph目录下生成了一系列的目录如下

而且其属主和属组都是ceph用户。为什么强调这个,在很多利旧的环境中,在清理集群时清理目录要清理这些目录下的文件。如果不清理,或者清理不干净,在ceph多次部署时会产生各种问题,本人在生产环境中就遇见过多次。文件清理不彻底,文件权限不正确的问题。

这里提供一个生产环境中清理ceph集群的命令

#停止服务
systemctl stop ceph-osd.target
systemctl stop ceph-mon.target
systemctl stop ceph-mgr.target #删除文件
rm -f /var/lib/ceph/bootstrap-mds/ceph.keyring
rm -f /var/lib/ceph/bootstrap-mgr/ceph.keyring
rm -f /var/lib/ceph/bootstrap-osd/ceph.keyring
rm-f /var/lib/ceph/bootstrap-rbd/ceph.keyring
rm -f /var/lib/ceph/bootstrap-rbd-mirror/ceph.keyring
rm -f /var/lib/ceph/bootstrap-rgw/ceph.keyring
rm -rf /etc/ceph/*
rm -fr /var/lib/ceph/mon/*
rm -fr /var/lib/ceph/mgr/* rm -rf /etc/systemd/system/multi-user.target.wants/ceph-volume*
rm -rf /etc/systemd/system/ceph-osd.target.wants/ceph-osd* 取消osd挂载
umount /var/lib/ceph/osd/*
rm -rf /var/lib/ceph/osd/*
rm -f /var/log/ceph/* #删除lv vg pv 分区信息
for i in `ls /dev/ | grep ceph-`; do j=/dev/$i/osd*; lvremove --force --force $j; done
for i in $(vgdisplay |grep "VG Name"|awk -F' ' '{print $3}'); do vgremove -y $i; done
for j in $(pvdisplay|grep 'PV Name'|awk '{print $3}'); do pvremove --force --force $j; done vgscan --cache
pvscan --cache
lvscan --cache

2.2 Mon 部署

1 生成uuid 即集群的fsid,即集群的唯一标识符
[root@mon01 ~]# uuidgen
51be96b7-fb6b-4d68-8798-665278119188 2 安装完ceph组件包之后,已经生成了/etc/ceph目录
接下来我们补充下ceph.conf 的配置文件 cat > /etc/ceph/ceph.conf <<EOF
fsid = 51be96b7-fb6b-4d68-8798-665278119188
mon_initial_members = mon01
mon_host = 192.168.200.11
public_network = 192.168.200.0/24
#cluster_network = 192.168.200.0/24
EOF
  • fsid 对应集群id
  • mon_initial_member 对应初始化的mon主机名,
  • mon_host 对应其IP地址
  • public_network 和cluster_network 则对应了之前介绍的公共网络和集群网络。

3、生成mon的私钥文件,进行身份验证

上文中提到集群内的组件访问也是需要认证的,Ceph 默认是使用Cephx 协议进行认证,此时分别给monbootstrap-osdclient.admin 来生成私钥文件

  • mon mon 私钥文件,用于mon进行身份认证
  • bootstrap-osd 是当你添加一个新的 OSD 到 Ceph 集群时,需要向集群引导这个 OSD。这个引导过程涉及到向 OSD 分配一个独特的标识符,并为其生成一个密钥以便在集群内进行身份验证。
  • client.admin 用于集群管理员进行管理使用的身份认证。
# mon key
ceph-authtool --create-keyring /tmp/ceph.mon.keyring \
--gen-key -n mon. --cap mon 'allow *' #bootstarp-osd key
ceph-authtool --create-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring \
--gen-key -n client.bootstrap-osd --cap mon 'profile bootstrap-osd' \
--cap mgr 'allow r' #client.admin key
ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring \
--gen-key -n client.admin --cap mon 'allow *' --cap osd 'allow *'\
--cap mds 'allow *' --cap mgr 'allow *'

cat /etc/ceph/ceph.client.admin.keyring

查看其结构也很容易理解,key 表示其私钥文件,caps mds = allow * ,表示对mds 拥有了所有的权限,其他同理。

[client.admin]
key = AQCni2NlDuN7ERAAYr/aL5A5R0OJFeBkwmrBjQ==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"

4、导入key到mon.keyring 文件中

将client.admin 和bootstrap-osd key,导入到mon的 keyring 文件中。并将keyring 文件复制到/etc/ceph/目录下

ceph-authtool /tmp/ceph.mon.keyring --import-keyring \
/etc/ceph/ceph.client.admin.keyring #将bootstap-osd的key 文件导入并复制到了 /var/lib/ceph/bootstrap-osd/ceph.keyring
ceph-authtool /tmp/ceph.mon.keyring --import-keyring \
/var/lib/ceph/bootstrap-osd/ceph.keyring
importing contents of /var/lib/ceph/bootstrap-osd/ceph.keyring into /tmp/ceph.mon.keyring

查看mon此时的keyring 文件,验证client.admin和client.bootstrap-osd keyring 已经导入

[root@mon01 ceph]# cat /tmp/ceph.mon.keyring
[mon.]
key = AQD8h2NlYzQWLRAA306ur5iOEjoHwarGx77FFg==
caps mon = "allow *"
[client.admin]
key = AQCni2NlDuN7ERAAYr/aL5A5R0OJFeBkwmrBjQ==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
[client.bootstrap-osd]
key = AQCKi2NlASwkDxAAPPXUeSwX8nQJJcJao+bgCw==
caps mgr = "allow r"
caps mon = "profile bootstrap-osd"

5 修改权限为ceph

chown ceph:ceph /tmp/ceph.mon.keyring

6、创建monmap

#单节点mon环境
monmaptool --create --add {hostname} {ip-address} --fsid {uuid} /tmp/monmap
monmaptool --create --add mon01 192.168.200.11 \
--fsid 51be96b7-fb6b-4d68-8798-665278119188 /tmp/monmap #多节点mon环境
monmaptool --create --add mon01 192.168.200.11 \
--add node2 192.168.200.12 --add node3 192.168.200.13 \
--fsid 51be96b7-fb6b-4d68-8798-665278119188 /tmp/monmap

6.1、什么是monmap? monmap是做什么用的?

  • Monitor Map: Ceph 集群中的 Monitors 负责维护集群的状态信息、监控数据等。monmap 包含了 Monitors 的信息,包括它们的主机名、IP地址以及集群的唯一标识(FSID)等。

  • 启动 Monitors: 在 Ceph 集群的启动过程中,Monitors 首先需要从 monmap 中获取集群的初始信息。monmaptool 的这个命令就是为了生成一个初始化的 monmap 文件,以供 Monitors 使用。这个文件会在 Monitors 启动时被加载。

  • 维护集群状态: 一旦 Monitors 启动,它们会使用 monmap 文件来维护集群的状态。Monitors 之间会相互通信,共享集群的状态信息。monmap 中包含的信息帮助 Monitors 确定其他 Monitor 节点的位置,从而进行集群管理和数据的一致性。

  • Monitor 选举: 当一个 Monitor 节点发生故障或新的 Monitor 节点加入集群时,集群需要进行 Monitor 的选举。monmap 包含的信息有助于集群中的 OSD(Object Storage Daemon)和客户端找到 Monitor 节点,并确保选举过程正确进行。

6.2 、怎么验证和查看当前集群的monmap ?

[root@mon01 tmp]# monmaptool --print /tmp/monmap
monmaptool: monmap file monmap
epoch 0
fsid 51be96b7-fb6b-4d68-8798-665278119188 #集群id
last_changed 2023-11-27 03:23:10.956578
created 2023-11-27 03:23:10.956578
min_mon_release 0 (unknown)
0: v1:192.168.200.11:6789/0 mon.mon01 #mon节点信息

6.3 、写错了怎么覆盖写?

# --clobber 参数 将会覆盖写
monmaptool --create --add mon01 192.168.200.12 --fsid \
91e36b46-8e6b-4ac6-8292-0a8ac8352907 /tmp/monmap --clobber

7 修改ceph 权限

chown -R ceph:ceph /tmp/{monmap,ceph.mon.keyring}

8 创建mon01 工作目录

#mkdir /var/lib/ceph/mon/{cluster-name}-{hostname}
sudo -u ceph mkdir /var/lib/ceph/mon/ceph-mon01 #默认cluster-name 就是ceph

9 用monitor map和keyring填充monitor守护程序,生mon01的数据库文件

#sudo -u ceph ceph-mon [--cluster {cluster-name}] \
#--mkfs -i {hostname} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring sudo -u ceph ceph-mon --cluster ceph --mkfs -i mon01 \
--monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring

验证

[root@mon01 ceph-mon01]# cat keyring
[mon.]
key = AQD8h2NlYzQWLRAA306ur5iOEjoHwarGx77FFg==
caps mon = "allow *"
[root@mon01 ceph-mon01]# ls
keyring kv_backend store.db
[root@mon01 ceph-mon01]# pwd
/var/lib/ceph/mon/ceph-mon01

【提示】mon 完成之后,即使key误删了,但admin keyring还在,可以使用ceph auth list 查看集群所有的keyring

完成第9步之后,在以systemd的方式拉起mon01的守护进场就算完成了mon的安装,但是在拉其服务之前,我们先介绍下两个概念,副本和纠删码

3、副本 or 纠删码

Ceph存储池在配置有两种分别是 副本池(Replicated Pool)纠删码池(Erasure-coded Pool),这两种类型也很好理解,如果是副本池,其存放是以副本的方式存放的,每份副本其数据是完全一致的,相当于1份数据存多份来冗余。

纠删码池一般Ceph是采用前向纠错码(Forward Error Correction,FEC)

FEC代码将K个chunk(以下称为块)数据进行冗余校验处理,得到了N个块数据。这N个块数据既包含原数据,也包括校验数据。这样就能保证K个块中如果有数据丢失,可以通过N个块中包含的校验数据进行恢复。

具体地说,在N=K+M中,变量K是数据块即原始数量变量M代表防止故障的冗余块的数量;变量N是在纠删码之后创建的块的总数。这种方法保证了Ceph可以访问所有原始数据,可以抵抗任意N–K个故障。例如,在K=10、N=16的配置中,Ceph会将6个冗余块添加到10个基本块K中。在M=N–K(即16–10=6)的配置中,Ceph会将16个块分布在16个OSD中,这样即使6个OSD掉线,也可以从10个块中重建原始文件,以确保不会丢失数据,提高容错能力。

简单来说就是 K个数据块 + M 个冗余块 = N个总块

【思考3】生产环境中我们是选副本还是纠删码呢?

性能优先选副本池,容量优先选纠删码。(本质上纠删码就是牺牲部分计算性能换存储容量)

4 故障域也称为冗余级别

在实际的生产环境中我们的数据都是存储在磁盘中的,磁盘对应OSD ,磁盘是服务器上的一个组件,服务器对应Host 而服务器是在机架中存放的,一个机柜RACK中有N个机架,而机柜是属于一个房间的ROOM,一个大型的数据中心(Data Center)可能有N个房间,而每个房间可能在同一个地区,也可以在不同地区。

对应其关系为 1Data Center = NRoom = NRACK = NHost = NOSD

总结:Ceph集群中有很多硬件设备,从上到下可能涉及某些逻辑单元,类似数据中心→设备所在机房→机架→行→服务器→OSD盘等的关系。那么,如何描述这些逻辑单元的关系、

Bucket 专门用于描述以上提到的这些逻辑单元属性,以便将来对这些属性按树状结构进行组织。(Bucket逻辑视图)(选取规则RuleSet) (磁盘设备Device) 组成了ceph的Crush Map.(混个脸熟即可,将来会重点介绍)

在ceph中使用 ceph osd tree 就可用查看该视图

上述视图中有3个机架 rack1 rack2 rack3 ,每个rack下分别由一个mon主机和两个osd 设备。

无论是副本池还是纠删码池,数据都是存储在osd中的,如果是副本池,默认3副本,那这3个osd,怎么选取了?

我们先不讨论Crush算法选取OSD的问题,我们就考虑一个问题,数据冗余问题。如果我们3个OSD 都在同一个节点,该节点down了,则我们数据都访问不了了,则我们称我们数据的冗余级别是OSD的级别的(Host下一级)。

如果我们的选取的3个OSD都在不同节点上(Host),但是这三个节点都在同一个机柜中(Rack),如果机柜断电了,则我们的数据无法访问了,我们称我们的冗余级别是节点级别(Host),同理3个OSD 在不同的机柜中,但在同一个ROOM中,我们称我们数据的冗余级别是RACK级别。

那我们怎么定义数据冗余级别了,osd_crush_chooseleaf_type 参数则可以定义,其值是一个数字 代表了类型。

ceph osd crush dump #可以查看到其type 

# types
type 0 osd
type 1 host
type 2 chassis #一般不使用,服务器机框。
type 3 rack
type 4 row
type 5 pdu
type 6 pod
type 7 room
type 8 datacenter

数字0 代表了其故障域是osd级别,虽然这种说法不严谨但是方便理解。后面我们在学习了Crush算法第二步之后就知道其OSD 是如何通过Bucket 和RuleSet 来选取OSD的,这里我们简单理解就是将3副本分散到3个osd就能满足要求。如果是数字1 表示其冗余级别是host 级别。要在不同的节点上,其他同理。

此实验环境中我们osd都在同一个节点上因此我们将其参数值设置为0

最后ceph.conf 文件修该为如下

最后我们启动mon服务

systemctl daemon-reload
systemctl start ceph-mon@mon01
systemctl enable ceph-mon@mon01 查看集群状态
[root@mon01 ceph-mon01]# ceph -s
cluster:
id: 51be96b7-fb6b-4d68-8798-665278119188
health: HEALTH_WARN
mon is allowing insecure global_id reclaim
1 monitors have not enabled msgr2 services:
mon: 1 daemons, quorum mon01 (age 6s)
mgr: no daemons active
osd: 0 osds: 0 up, 0 in data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 0 B used, 0 B / 0 B avail
pgs:

如果ceph状态显示如上图,恭喜你,表示第一个mon已经成功部署了.

mon组件可以说是Ceph最重要的组件了,因此本章节对其每一步操作都做了详细说明,剩下的mgr osd的部署则会简单很多,由于篇幅所限,我们将在下一章节继续。

每天5分钟复习OpenStack(十一)Ceph部署的更多相关文章

  1. 理解 OpenStack + Ceph (1):Ceph + OpenStack 集群部署和配置

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  2. OpenStack Kilo版加CEPH部署手册

    OpenStack Kilo版加CEPH部署手册 作者: yz联系方式: QQ: 949587200日期: 2015-7-13版本: Kilo 转载地址: http://mp.weixin.qq.co ...

  3. 理解 OpenStack + Ceph (5):OpenStack 与 Ceph 之间的集成 [OpenStack Integration with Ceph]

    理解 OpenStack + Ceph 系列文章: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 (5)Ceph 与 OpenS ...

  4. Ceph部署(二)RGW搭建

    背景 Ceph RGW简介 Ceph RGW基于librados,是为应用提供RESTful类型的对象存储接口.RGW提供两种类型的接口: 1) S3:兼容Amazon S3RESTful API: ...

  5. OpenStack 对接 Ceph

    [TOC]   1. Openstack 与 Ceph 1.1. Ceph 简介 Ceph 是当前非常流行的开源分布式存储系统,具有高扩展性.高性能.高可靠性等优点,同时提供块存储服务(RBD).对象 ...

  6. OpenStack 使用Ceph 配置指导

    概述 Ceph 作为分布式文件系统,不但具有高可靠性.高扩展性.高性能. 也是统一存储系统.支持对象存储.块存储.文件存储,本文介绍怎样使用Ceph 块存储作为OpenStack的Glance.Nov ...

  7. kolla安装Queens版本OpenStack(ceph后端)

    OpenStack all-in-one部署: 本次部署为OpenStack Queens版本部署,使用All-in-one,单节点部署. 物理资源:8核,32GB,硬盘400GB(3个盘),2网卡. ...

  8. openstack高可用集群21-生产环境高可用openstack集群部署记录

    第一篇 集群概述 keepalived + haproxy +Rabbitmq集群+MariaDB Galera高可用集群   部署openstack时使用单个控制节点是非常危险的,这样就意味着单个节 ...

  9. ceph 部署步骤和原理理解

    1.ceph的官方源在国外,网速比较慢,此处添加ceph源为阿里源(每个节点上均执行) vim /etc/yum.repos.d/ceph.repo [Ceph] name=Ceph packages ...

  10. 高可用OpenStack(Queen版)集群-14.Openstack集成Ceph准备

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

随机推荐

  1. 青少年CTF-Web-CheckMe01

    题目描述 半颗星的简单题,CheckMe01 启动题目,并访问. 解题过程 访问题目页面,提示我们需要输入一个Key. 随便输入一个值,发现出现了一些代码. 我们仔细阅读代码,来了解这段代码是干什么的 ...

  2. Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN)

    Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN) 来源: KDD'2023 Google ...

  3. WPF学习 - 动画基础(2)

    上一篇文章粗略的介绍了一下Animation类.本篇介绍一下Storyboard. Storyboard,姑且翻译成"故事板"吧.实际上它是一个Animation对象的容器,可以容 ...

  4. grinder使用入门

    安装配置 自动安装脚本编写 移步我的github下载脚本,只要修改下配置信息,即可完成安装 环境变量设置:

  5. JDK17和JDK8在windows上同时安装方便切换

    参考:https://blog.csdn.net/chencaw/article/details/121674479 一.JDK8的安装 1.电脑上已经安装了JDK8,安装主要步骤如下 (1)创建JA ...

  6. 【译】ASP.NET Core在 .NET Core 3.1 Preview 1中的更新

    .NET Core 3.1 Preview 1现在可用.此版本主要侧重于错误修复,但同时也包含一些新功能. 这是此版本的ASP.NET Core的新增功能: 对Razor components的部分类 ...

  7. 记一次 .NET 某电力系统 内存暴涨分析

    一:背景 1. 讲故事 前些天有位朋友找到我,说他生产上的程序有内存暴涨情况,让我帮忙看下怎么回事,最简单粗暴的方法就是让朋友在内存暴涨的时候抓一个dump下来,看一看大概就知道咋回事了. 二:Win ...

  8. ionic app调试问题

    以下是一些ionic app在模拟器中的调试问题: 1. CORS问题 官方原文以及解释:Handling CORS issues in Ionic 国内翻译:彻底解决Ionic项目中的跨域问题 2. ...

  9. Building-Mobile-Apps-with-Ionic-2中文翻译工作

    最近没啥工作量, 然后学完了这本书, 接着又茫然找不到该干啥, 所以想着何不翻译这个书呢. 这本书首先给我们普及了Ionic 2的基础知识, Ionic 2和Ionic 1有本质上的区别, Ionic ...

  10. strcpy()函数详解

    strcpy()函数是C语言中的一个复制字符串的库函数,以下将详细解释说明一下: · 函数声明以及实现代码 char *strcpy(char *dst, const char *src);char ...