Iscsi

  • 一、iscsi简介
    • 二、NAS(网络附加存储服务器)简介
      • 三、SAN(存储局域网)简介
        • 四、ISCSI的创建
          • 五、关于iscsi的防火墙相关设置

一、iscsi简介

如果你的系统需要大量的磁盘容量,但是身边却没有外接存储设备,仅有个人计算机时,那该怎么办?
此时,通过网络的SCSI磁盘(ISCSI)就能够提供帮助。这个iscsi是将来自网络的数据仿真成本机的SCSI设备,因此可以进行诸如LVM等方面的操作,而不是单纯使用服务器端提供的文件系统而已。
作为服务器的系统,通常是需要存储设备的,而存储设备除了可以使用系统内置的磁盘之外,如果内置的磁盘容量不够大,而且也没有额外的磁盘插槽可用时,那么常见的解决方案就是增加NAS:Network Attached Storage(网络附加存储服务器)或外接式存储设备。再高档一点的系统可能就会用到SAN:Storage Area Network(存储局域网)
不论是哪一种架构,它们的内部硬盘通常是以磁盘阵列(RAID)作为基础的。
由于企业的数据量越来越大,而且重要性与保密性越来越重要,尤其类似数据库的内容,常常容量单位是以TB、PB、EB进行计算。所以磁盘阵列的应用就很重要了。
那么磁盘阵列通常是在哪里呢?
1.主机内部有磁盘阵列控制卡,可以自行管理磁盘阵列,不过想要提供磁盘阵列的容量,需要通过额外的网络服务才行;
2.外接式磁盘阵列设备,就是单纯的磁盘阵列设备,必须通过某些接口连接到主机上,主机也要安装适当的驱动程序后才能捕捉到这个设备所提供的磁盘容量。
不过在当前的信息社会,很少听到内置或外接的RAID了,常常听到的就是NAS和SAN。

二、NAS(网络附加存储服务器)简介

NAS其实就是一部客制化好的主机,只要将NAS连接上网络,那么在网络上面的其他主机就能够存取NAS上的资料了。简单的说,NAS就是file server,不过NAS由于也是接在网络上,所以如果网络上有某个用户大量存取NAS上的数据时,是很容易造成网络停顿的问题的。低阶的NAS通常会使用Linux系统搭配软件磁盘阵列来提供大容量文件系统。不过效能有待加强!此外,NAS也通常支持TCP/IP,并会提供NFS、SAMBA、FTP等常见的通讯协议来提供客户端取得文件系统。
那为什么不直接使用个人计算机安装Linux再搭配相关的服务,即可提供NAS预计要提供的大容量空间了?
因为通常NAS还会包括很多组态的接口,通常是利用Web接口来控制磁盘阵列的设定状况、提供IP或其他相关网络设定,以及是否提供某些特定的服务等等。因为具有较为亲和的操作与控制接口,对于非IT的人员来说,控管较为容易。这也是NAS存在的目的。

三、SAN(存储局域网)简介

其实NAS就是一台可以提供大容量文件系统的主机。那我们知道单部主机能够提供的插槽再怎么说也是有限的,所以并不能无限制的安插磁盘在同一台实体主机上。但是如果偏偏就是有大量磁盘使用的需求,这时就要使用到SAN。最简单的看法,就是将SAN视为一个外接式的储存设备。只是单纯的外接式储存设备,仅能透过某些接口(如SCSI或eSATA)提供单一主机使用,而SAN却可以透过某些特殊的接口或信道来提供局域网络内的所有机器进行磁盘存取。
要注意,SAN是提供磁盘(block device)给主机用,而不是像NAS提供的是网络协议的文件系统(NFS, SMB. . .),这两者的差异挺大的。因此,挂载使用SAN的主机会多出一个大磁盘,并可针对SAN提供的磁盘进行分割与格式化等动作。另外,既然SAN可以提供磁盘,而NAS则是提供相关的网络文件系统,那么NAS能不能透过网络去使用SAN所提供的磁盘呢?答案当然是可以。
因为SAN最大的目的就是提供磁盘给服务器主机使用,NAS也是一部完整的服务器,所以NAS当然可以使用SAN。同时其他的网络服务器也能够使用这个SAN来进行数据存取。

总结

SAN是提供LUN方式给客户端使用,客户端需要MKFS,再MOUNT成文件系统。NAS是直接以文件系统方式提供给客户端使用,客户端不需要MKFS,如FTP、目录共享。

既然SAN开发的目的是提供大量的磁盘给用户,那么传输的速度当然是非常重要的。因此,早期的SAN大多配合光纤信道(Fibre Channel)来提供高速的数据传输。目前标准的光纤信道是速度是10GB,不过,使用光纤等技术较高的设备,当然就比较贵一些。
由于以太网络盛行,加上技术成熟,现今的以太网络媒体(网络卡、交换器、路由器等设备)已经可以达到很高的速度了,离SAN的光纤信道速度其实差异已经缩小很多了。那么是否可以透过这个以太网络接口来连接到SAN的设备呢?这就是接下来要提到的ISCSI架构。
早期的企业使用的服务器若有大容量磁盘的需求时,通常是透过SCSI来串接SCSI磁盘,因此服务器上面必须要加装SCSI适配卡,而且这个SCSI是专属于该服务器的。后来这个外接式的SCSI设备被上述提到的SAN的架构所取代,在SAN的标准架构下,虽然有很多的服务器可以对同一个SAN进行存取的动作,不过为了速度需求,通常使用的是光纤信道。不但设备贵,服务器上面也要有光纤接口,很麻烦。所以光纤的SAN在中小企业很难普及。
后来网络实在太普及,尤其是以IP封包为基础的LAN技术已经很成熟,再加上以太网络的速度越来越快,所以就有厂商将SAN的连接方式改为利用IP技术来处理。然后再透过一些标准的制定,最后就得到Internet SCSI了。iSCSI主要是透过TCP/IP的技术,将储存设备端透过iSCSI target(iSCSI目标)功能,做成可以提供磁盘的服务器端,再透过iSCSI initiator(iSCSI初始化用户)功能,做成能够挂载使用iSCSI target的客户端,如此便能透过iSCSI协议来进行磁盘的应用。
也就是说,iSCSI这个架构主要将储存装置与使用的主机分为两个部分。

iSCSI target:储存设备端,存放磁盘或RAID的设备,目前也能够将Linux主机仿真成iSCSI target了。目的在于提供其他主机使用的磁盘;iSCSI initiator:能够使用target的客户端,通常是服务器。也就是说,想要连接到iSCSI target的服务器,也必须要安装iSCSI initiator的相关功能后才能够使用iSCSI target提供的磁盘。

四、ISCSI的创建


Internet Small Computer System Interface:Internet小型计算机系统接口,是一个基于TCP/IP协议,主要用于通过IP网络仿真SCSI,从而为远程块存储设备提供数据传输和管理。说白了,就是通过网络由专门的服务器提供存储管理,以实现数据的远程储存,便于数据的集中管理,从而简化了数据复制、迁移和容灾。
1.名词解释

ACL:访问权限控制列表,用来验证客户端启动器的访问,通常是客户端iSCSI启动器的IQN名称。IQN:用于标识单个iSCSI目标和启动器的唯一名称(全部小写)。WWN:用于标识单个光纤通道端口和节点的唯一编号。TARGET:iSCSI服务器上的存储资源。LUN:iSCSI服务器上的块设备。initiator(启动器):以软件或硬件实施的iSCSI客户端。NODE:单个iSCSI启动器或者目标。TPG:启动器或者目标上的单个IP连接地址。Portal:网络接口及端口。

2.实验环境准备

主机 IP
server端(target) 192.168.1.60 /dev/sdb
client端(initiator) 192.168.1.61

3.基本概念
在SAN中,主机一般都是Initiator,存储设备则是Target。
Initiator(发起者)
(1)SCSI会话的发起方。
(2)向Target请求LUN,并将数据的读写指令发送给Target。
Target(目标)
(1)默认采用TCP3260端口。
(2)接受SCSI会话的一方。
(3)它接收来自Initiator的指令,为Initiator提供LUN,并实现对LUN的读写。
IQN
iqn.2020-06.com.redhat:737db83a23df 全球唯一名称,用于以强制命令格式来识别启动器和目标iqn表示此名称将使用域作为其标识符。
yyyy-mm:拥有域名的第一个月 。
com.redhat:逆向域名 。
optional_string:以冒号为前缀的可选字符串,根据需要分配。
4.首先在server端操作

[root@server ~]# yum -y install targetd targetcli
[root@server ~]# systemctl start target
[root@server ~]# systemctl enable target
[root@server ~]# systemctl status target
● target.service - Restore LIO kernel target configurationLoaded: loaded (/usr/lib/systemd/system/target.service; enabled; vendor preset: disabled)Active: active (exited) since 三 2021-01-27 02:37:56 EST; 26s agoMain PID: 16402 (code=exited, status=0/SUCCESS)
...

5.设置防火墙

[root@server ~]# firewall-cmd --add-port=3260/tcp --permanent
success
[root@server ~]# firewall-cmd --reload
success
[root@server ~]# firewall-cmd --list-ports
3260/tcp

6.执行targetcli工具
先把准备共享的块做出来,创建一个target,在target上创建LUN,一个LUN连接一个块。
注意:执行完targetcli命令出错,是因为缺少包导致的,需要下载一个包。

[root@server ~]# yum -y install python-rtslib

开始执行

[root@server ~]# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'. /> ls
o- / ............................................................ [...]o- backstores ................................................. [...]| o- block ..................................... [Storage Objects: 0]| o- fileio .................................... [Storage Objects: 0]| o- pscsi ..................................... [Storage Objects: 0]| o- ramdisk ................................... [Storage Objects: 0]o- iscsi ............................................... [Targets: 0]o- loopback ............................................ [Targets: 0]

7.server端指定要发布的磁盘(块设备LUN)

/> /backstores/block create server0.disk1 /dev/sdb
Created block storage object server0.disk1 using /dev/sdb.

注意:server0.disk1是给/dev/sdb转化成块的名字。
8.创建iqn名字即创建ISCSI对象
iqn:iSCSI Qualified Name(ISCSI限定名称)

/> /iscsi create iqn.2020-05.com.bdqn:disk1
Created target iqn.2020-05.com.bdqn:disk1.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.

9.设置ACL将ISCSI对象与客户端IP或主机名绑定

/> /iscsi/iqn.2020-05.com.bdqn:disk1/tpg1/acls create iqn.2020-05.com.bdqn:client1
Created Node ACL for iqn.2020-05.com.bdqn:client1

注意:iqn.2020-05.com.bdqn:client1是initiator的名字,需要在客户端中设置的。
10.创建LUN并绑定块

/> /iscsi/iqn.2020-05.com.bdqn:disk1/tpg1/luns create /backstores/block/server0.disk1
Created LUN 0.
Created LUN 0->0 mapping in node ACL iqn.2020-05.com.bdqn:client1

注意:可以查看/etc/target/saveconfig.json配置文件,该配置文件保存着ISCSI的配置。
11.client端上操作

[root@client ~]# yum -y install iscsi-initiator-utils

12.给initiator命名

[root@client ~]# vim /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2020-05.com.bdqn:client1

注意:这个名字是刚才在服务端做ACLS允许通过的名单里的名字。
13.启动服务

[root@client ~]# systemctl start iscsi
[root@client ~]# systemctl enable iscsi
[root@client ~]# systemctl status iscsi
● iscsi.service - Login and scanning of iSCSI devicesLoaded: loaded (/usr/lib/systemd/system/iscsi.service; enabled; vendor preset: disabled)Active: inactive (dead)
Condition: start condition failed at 三 2021-01-27 02:56:26 EST; 12s agoDocs: man:iscsiadm(8)man:iscsid(8)

14.发现存储

[root@client ~]# iscsiadm -m discovery -t st -p 192.168.1.60
192.168.1.60:3260,1 iqn.2020-05.com.bdqn:disk1

可以用iscsiadm --help查看下语法。
iscsiadm是基于命令行的iscsi管理工具,提供了对iSCSI节点、会话、连接以及发现记录的操作。
iscsiadm的使用说明可以查看/usr/share/doc/iscsi-initiator-utils-6.2.0.742/README
也可以运行man iscsiadm或iscsiadm --help使用。
15.参数解释

-m:{discovery|node|session|iface} {发现某服务器是否有target输出,以及输
出了哪些target|管理跟某target的关联关系|会话管理|接口管理}。-d:{0-8} 打印调试信息,有0到8这9个等级。-t:这里可以使用的类型为sendtargets(可简写为st)、slp、fw和isns,此选项仅用
于discovery模式,且目前仅支持st、fw和isns;其中st表示允许每个iSCSItarget
发送一个可用target列表给initiator。-T:用于指定target的名字。-p:指定target服务的IP和端口, -p 192.168.1.55:3260。-o:指定针对discoverydb数据库的操作,其仅能为new、delete、update、show
和nonpersistent其中之一。-I:指定执行操作的iSCSI接口,这些接口定义在/var/lib/iscsi/ifaces中。-l:登录节点。-u:登出节点(服务器)。

16.登录存储/连接target

[root@client ~]# iscsiadm -m discovery -t st -p 192.168.1.60 -l
192.168.1.60:3260,1 iqn.2020-05.com.bdqn:disk1
Logging in to [iface: default, target: iqn.2020-05.com.bdqn:disk1, portal: 192.168.1.60,3260] (multiple)
Login to [iface: default, target: iqn.2020-05.com.bdqn:disk1, portal: 192.168.1.60,3260] successful.

17.验证iscsi连接,查看是否得到外界磁盘

[root@client ~]# lsscsi
[0:0:0:0]    disk    VMware,  VMware Virtual S 1.0   /dev/sda
[2:0:0:0]    cd/dvd  NECVMWar VMware IDE CDR10 1.00  /dev/sr0
[3:0:0:0]    disk    LIO-ORG  server0.disk1    4.0   /dev/sdb

然后就可以像操作本地磁盘一样来操作iscsi磁盘了。

[root@client ~]# gdisk /dev/sdb
...
Number  Start (sector)    End (sector)  Size       Code  Name1            2048        10487807   5.0 GiB     8300  Linux filesystem2        10487808        20973567   5.0 GiB     8300  Linux filesystem
[root@client ~]# partprobe /dev/sdb
[root@client ~]# cat /proc/partitions
major minor  #blocks  name8        0   20971520 sda8        1    1048576 sda18        2   19921920 sda211        0    1048575 sr0253        0   17821696 dm-0253        1    2097152 dm-18       16   20971520 sdb8       17    5242880 sdb18       18    5242880 sdb2

这里将/dev/sdb1分区挂载到/mnt/iscsi目录中使用。

[root@client ~]# mkdir /mnt/iscsi
[root@client ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1              isize=512    agcount=4, agsize=327680 blks=                       sectsz=512   attr=2, projid32bit=1=                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=1310720, imaxpct=25=                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2=                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@client ~]# mount /dev/sdb1 /mnt/iscsi/
[root@client ~]# mount | tail -1
/dev/sdb1 on /mnt/iscsi type xfs (rw,relatime,attr2,inode64,noquota)
[root@client ~]# df -hT /mnt/iscsi/
文件系统       类型  容量  已用  可用 已用% 挂载点
/dev/sdb1     xfs  5.0G  33M  5.0G 1% /mnt/iscsi

如果加入开机自动挂载,需要在挂载选项中添加_netdev选项。

[root@client ~]# vim /etc/fstab
...
/dev/sdb1       /mnt/iscsi     xfs    defaults,_netdev   0     0
[root@client ~]# mount -a
五、关于iscsi的防火墙相关设置

注意:iscsi,网络存储,经过网络,那么就必须要注意安全。这里注意是以防火墙来体现安全。
可以再开一台虚拟机。当做iscsi客户端,看看是否能够发现iscsi存储。

[root@localhost ~]# yum -y install iscsi*
[root@localhost ~]# systemctl start iscsi
[root@localhost ~]# iscsiadm -m discovery -t st -p 192.168.1.60
192.168.1.60:3260,1 iqn.2019-05.com.bdqn:disk1

发现同样可以发现网络存储,可以想到刚开始做的防火墙的规则:firewall-cmd --permanent --add-port=3260/tcp。这一条命令只是打开3260端口,但是却有一个问题,那就是谁都可以访问3260端口,那么怎么做才能够限制其他人访问呢?
1.查看防火墙状态

[root@server ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled;
vendor preset: enabled)Active: active (running) since Tue 2019-05-21 22:13:17 CST; 5h 56min
left

2.开启和关闭防火墙的命令

systemctl start firewalldsystemctl stop firewalld

3.查看开放端口命令

[root@server ~]# firewall-cmd --zone=public --list-ports
3260/tcp

4.使用防火墙富规则
实现只能够添加允许的客户端IP

[root@server ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.61 port port=3260 protocol=tcp accept'
success
[root@server ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.61 port port=3260 protocol=tcp accept' --permanent
[root@server ~]# firewall-cmd --list-rich-rules
rule family="ipv4"
source address="192.168.1.61"
port port="3260"
protocol="tcp"
accept

5.修改IP
而且在上面创建target的时候,其实会看到0.0.0.0,其实是我们把0.0.0.0改成对应的客户端的IP了。

[root@server ~]# targetcli
/iscsi/iqn.20...qn:disk1/tpg1> portals/ delete 0.0.0.0 3260
Deleted network portal 0.0.0.0:3260
/iscsi/iqn.20...qn:disk1/tpg1> portals/ create 192.168.1.61 3260
Using default IP port 3260
Created network portal 192.168.1.61:3260.
/iscsi/iqn.20...qn:disk1/tpg1> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json
[root@server ~]# systemctl restart target.service

6.验证

[root@localhost ~]# iscsiadm -m discovery -t st -p 192.168.1.60
iscsiadm: cannot make connection to 192.168.1.60: Connection refused
iscsiadm: cannot make connection to 192.168.1.60: Connection refused
iscsiadm: cannot make connection to 192.168.1.60: Connection refused
iscsiadm: cannot make connection to 192.168.1.60: Connection refused

7.假设服务器又开启了httpd服务
那么如果没有设置的话,其他机器是无法访问的。怎么设置才能够让其他机器访问到呢?

[root@server ~]# yum -y install httpd
[root@server ~]# systemctl start httpd
[root@server ~]# cat > /var/www/html/index.html <<EOF
> How are you?
> I'm fine!
> EOF
[root@server ~]# curl 127.0.0.1
How are you?
I'm fine!
[root@localhost ~]# curl 192.168.1.60
curl: (7) Failed connect to 192.168.1.60:80; No route to hostu

8.添加规则

[root@server ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.61 port port=80 protocol=tcp accept'
success
[root@server ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.61 port port=80 protocol=tcp accept' --permanent
success

9.客户端验证可以访问

[root@localhost ~]# curl 192.168.1.60
How are you?
I'm fine!

如果想要使同网段都可以访问,那么IP就可以设置为:192.168.1.0/24。
10.iscsi总结
target端,也就是服务端,先将需要分享的磁盘,用targetcli工具分享出去。
这里注意targetcli工具制作的过程:

(1)创建对应的块存储block storage。语法是create + 名字+ /dev/sd*(2)给要分享的磁盘命名。安装iqn(iscsi规定的名称类型)
名称类型是iqn+yyyy-mm+逆向域名+备注。备注信息可以不写(3)然后对这个刚刚建好的iqn进行设置,进入/ISCSI/iqn.../tpg下可以看到3个选项。
acls:这里直接create,注意的是,这里指向的是客户端的名字。
luns:指定的是刚才创建的block storage。
portals:允许接收,允许查看,客户端的IP+端口。

initiator端,也就是客户端,需要下载的是iscsi服务。

(1)开启服务之后,直接就发现iscsi服务,可以使用iscsiadm --help来查看都需要添加哪些参数。
iscsiadm -m discovery -t st -p 192.168.**(2)发现之后,直接在发现的长命令后面加上一个"-l"就可以了,表示登录、连接。(3)然后就可以在/proc/partitions中看到或者fdisk -l来查看是否连接成功,如果没有连接成功则需要考虑防火墙、或者重启服务。(4)剩下的就和操作本地磁盘一样了,分区、格式化、挂载。
需要注意的是,如果在/etc/fstab目录下添加开启自启动的话,需要添加选项格式_netdev。

Linux系统Iscsi创建相关推荐

  1. Linux系统之创建逻辑卷

    Linux系统之创建逻辑卷 一.磁盘分区 二.创建PV物理卷 三.创建卷组,指定PE大小为12M 四.创建逻辑卷,大小50个PE 五.格式化逻辑卷,并挂载 1.格式化逻辑卷 2.永久挂载 一.磁盘分区 ...

  2. Linux系统如何创建和挂载XFS文件系统

    Linux系统如何创建和挂载XFS文件系统?XFS是高性能文件系统,由于它的高性能,XFS成为了许多企业级系统的首选,特别是有大量数据,需要结构化伸缩性和稳定性的.下面我们来看看如何实现创建和挂载XF ...

  3. 在linux系统中创建文件夹,Linux系统中创建文件夹命令详解

    Linux系统中创建一个新的文件夹我们可以使用命令来执行,下面由学习啦小编为大家整理了Linux系统中创建文件夹命令详解,希望对大家有帮助! Linux系统中创建文件夹命令详解 一.mkdir命令使用 ...

  4. linux如何创建符号文件,Linux 系统如何创建符号链接

    欢迎,来自IP地址为:122.6.224.206 的朋友 本文将详细讲解 Linux 系统中符号链接的概念和用法,以及在使用符号链接时需要注意的问题. 什么是 Linux 系统符号链接以及符号链接的用 ...

  5. linux如何生成tar文件内容,在Linux系统中创建tar.gz文件的方法及实例讲解

    本文介绍在Linux系统中创建tar.gz文件的方法,及实例讲解. 介绍 tar存档是一个文件,用于存储其他文件的集合,包括有关它们的信息,例如所有权.权限和时间戳. 在Linux操作系统中,可以使用 ...

  6. Linux系统中创建大文件,并作为文件系统使用

    在LInux系统的使用过程中,有时候会遇到诸如某个磁盘分区的大小不够用了,导致其下的文件系统不能正常写入数据.亦或者是系统swap分区太小,不够用或者不满足条件而导致的其他一系列问题.如果我们系统上挂 ...

  7. linux系统下创建文件系统

    任何硬盘和u盘等存储介质都需要建立文件系统之后,才能使用.我们u盘和硬盘之所以跟买的容量不一样,就是因为里面存储着文件系统.没有文件系统,那就是纯粹的硬件,是不能使用的.在windows中我们可以格式 ...

  8. linux系统下创建symlink(@)即文件软链接(快捷方式)的命令

    问题起源: 在一个项目中看到有bert@文件名及大量的bert.20200501,bert.20200601等文件夹? 第一个问题文件名带@符号代表什么 第二个问题这样的做意义是什么 解答: 第一个问 ...

  9. linux批量创建系统,linux系统批量创建用户

    脚本目的:批量创建linux系统用户 说明:要创建用户的主机密码写入到ip.txt文件中 [root@thsf02 scripts]# cat ip.txt 10.165.123.0 10.172.4 ...

最新文章

  1. android中解压文件
  2. CCNet 的 Build 流程
  3. 商业实战第三场 电视直销好记星
  4. 【数据挖掘知识点五】层次聚类方法的理解
  5. 关于可变字符串StringBuffer和String的区别总结
  6. Go Web:HttpRouter路由(一)
  7. Excel表格从指定部分重新分页打印的两种方法
  8. 安装和启动mysql
  9. “小程序肯定会取代 App!” | 人物志
  10. 有关计算机编程论文,有关计算机程序的论文范文
  11. TortoiseSVN图标介绍
  12. 24种编程语言的Hello World程序
  13. 快速明白ARCore + 上手
  14. C++变量前面加下划线的含义
  15. taocat服务器的作用,随笔2_tww
  16. 深夜看了张一鸣的微博,我不得不惊
  17. FillRect、FrameRect与Rectangle矩形绘制函数使用对比分析
  18. python因子分析案例_因子分析及python实现(一)
  19. 软工大牛Collin McMillan及其顶会论文解读
  20. vue-seamless-scroll组件踩坑指南

热门文章

  1. 数据库的前世今生04
  2. JS 正则表达式常用方法
  3. 5种jQuery美化下拉菜单列表插件
  4. 制作了一个微信公众号导航的网站 http://www.wxgzh.in
  5. 腾讯|阿里|百度|字节跳动人才体系的职位层级、薪酬、晋升标准
  6. MFC 让对话框不显示在任务栏和桌面
  7. php imagecreate 中文,imagecreate
  8. Flutter快学快用开篇词 通往大前端的一把关键钥匙 Flutter
  9. 判断网站是哪种数据库
  10. ALGO-998 娜神平衡