NFS

Wesley13
• 阅读 733

环境:VMware-Workstation-12-Pro,Windows-10,CentOS-7.5,Xshell5

[TOC]

NFS介绍

什么是NFS(Network File System)

简单来说NFS就是实现文件共享功能的,与windows文件共享功能类似,但本篇博客只讨论多台Linux
服务器之间通过NFS共享文件,不涉及windows。NFS一般的用法是,选一台Linux服务器作为NFS服务
端,把该机器上某个目录共享出去,一般是共享到局域网内,然后局域网内的其它机器都连接上这台
服务器,操作NFS服务端共享出来的指定目录。

NFS也是一套标准的文件系统协议,是1984年Sun Microsystems开发的,现在是RFC维护,最新
版本是NFSv4.2。

我们知道把数据共享给其它机器,那是需要联网传输数据的,而NFS本身不具备通过网络传输数据的
功能,而是依赖RPC服务(Remote Procedure Call)实现的,RPC最早也是Sun Microsystems
开发的,现在也是RFC标准,RPC传输数据是基于TCP/UDP协议的,使用的是固定端口111。

搭建NFS服务需要的软件包

在CentOS7里,如果我们使用yum安装nfs-utils,不要着急确认,可以看到提示的依赖信息如下
图所示:

NFS

看到了吧,其中我们需要关心的的依赖软件包就是rpcbind。也就是说搭建NFS服务需要安装两个软件
包nfs-utils和rpcbind,分别对应了NFS母体和其所需要的数据传输服务RPC,不过使用yum安装系统
会自动处理依赖,即只需安装nfs-utils包即可。

如果我们使用yum卸载nfs-utils包,其安装时所对应的依赖,都是不会被卸载的。

安装完毕之后我们可以使用rpm -ql nfs-utils,看一下该包里都有哪些命令和文件:

[root@nfs-server ~]# rpm -ql nfs-utils
/usr/lib/systemd/system/nfs-server.service
/usr/sbin/exportfs
/usr/sbin/showmount
/var/lib/nfs/etab

上面的输出省略了一些内容。

极简步骤搭建NFS服务

俗话说的好,光说不练假把式,本节我们就用最少的步骤,完全不考虑原理,专注实现功能,让读者
快速看到效果。

准备两台机器

首先启动两台Linux虚拟机,关闭防火墙和SELinux,使用Xshell连接好。最关键的,IP地址和
主机名按照下面的表格配置:

机器

主机名

公网IP

内网IP

1号虚拟机

nfs-server

10.0.0.31

10.0.0.7

2号虚拟机

web-client

172.16.1.31

172.16.1.7

这里我简单解释下,1号虚拟机是NFS服务器,就是共享目录给别人用的机器,2号虚拟机是客户端,
就是使用1号机器共享出来的目录的机器。这里我给每个机器都配置了两块网卡,这不是必须的,
事实上一块网卡也能实现效果。另外具有一定计算机网络背景知识的读者可以看到,我写的虽然是
公网IP,其实也是用于局域网的IP来模拟的,如果在生产环境中,会根据实际需要,替换成真正的
公网IP地址。

在下面的叙述中,有时我会显示说明实在哪台机器上进行操作,有时读者则需要通过主机名来判断,
当前需要操作哪台机器。

推荐使用克隆虚拟机来搭建测试环境,关于虚拟机克隆以及克隆后添加网卡和修改网络参数,可以
参考这里:

配置服务端(nfs-server)

1 安装nfs-utils

[root@nfs-server ~]# yum install nfs-utils -y

2 重启rpcbind服务

[root@nfs-server ~]# systemctl restart rpcbind

3 配置/etc/exports

[root@nfs-server ~]# vim /etc/exports
[root@nfs-server ~]# cat /etc/exports
/data *(rw)

4 创建要共享的目录并更改所有者为nfsnobody

[root@nfs-server ~]# mkdir /data
[root@nfs-server ~]# chown -R nfsnobody:nfsnobody /data

5 重启nfs-server服务

[root@nfs-server ~]# systemctl restart nfs-server

配置客户端(web-client)

1 安装nfs-utils

[root@web-client ~]# yum install nfs-utils -y

2 重启rpcbind服务

[root@web-client ~]# systemctl restart rpcbind

3 挂载远端(172.16.1.31)上的目录

[root@web-client ~]# mkdir /data
[root@web-client ~]# mount -t nfs 172.16.1.31:/data /data

4 测试

[root@nfs-server ~]# ls /data
f1.txt  f2.txt  f3.txt
[root@web-client ~]# ls /data
f1.txt  f2.txt  f3.txt
[root@web-client ~]# echo "123456" > /data/f4.txt
[root@web-client ~]# ls /data
f1.txt  f2.txt  f3.txt  f4.txt
[root@web-client ~]# cat f4.txt 
123
[root@nfs-server ~]# ls /data
f1.txt  f2.txt  f3.txt  f4.txt
[root@nfs-server ~]# cat /data/f4.txt 
123456

从上述测试效果中可以看出,客户挂载完毕远端共享出来的目录/data后,在客户端操作/data目录
几乎和操作本地目录一致,也就是对客户端来说远端nfs服务器是透明的,无需关心,正常操作/data
目录即可。无论是在客户端还是在本地端操作/data目录,操作的都是同一块磁盘,读写的都是相同
的物理空间。

NFS服务简单执行流程

比如现在NFS服务器共享了一个/data目录给客户端,客户端要往/data目录里写入数据,大致会经过
如下几个步骤:

  1. 客户端把请求传递给自己的rpcbind服务
  2. rpcbind通过TCP/UDP协议把请求传递给服务端的rpcbind服务
  3. 服务端的rpcbind请求传递给服务端的nfs服务
  4. 服务端的nfs服务,操作本地件,写入数据

可以看到rpcbind服务在NFS共享服务之间起到了中介的作用,事实上nfs服务具有非常多的端口,
而且是随机的,直接通过这些端口与客户端操作非常不便,而rpcbind使用的是固定端口111,
这样客户端与服务端只需要监听111端口,即可完成通信。正是rpcbind在其中承担了客户端和
服务端之间端口映射与转换的工作。

基本了解nfs共享服务的操作流程之后,下面我们就开始详细说说上面每一步的操作步骤都是何含义,
并且对关键部分进行展开细说,下面很多内容都会提到上面的极简案例。首先一个比较关键的,就是
要弄明白,共享文件的访问权限。

NFS文件访问权限

要共享一个目录给别人用,我们直觉能想到的就是,需要共享什么目录,共享给谁,这两个基本问题。
另外还有一个非常重要的部分:共享文件的权限。我们上面的极简示例中,服务端共享/data目录,
客户端挂载/data目录,之后就可正常读写,且慢,大家有没有注意到我在客户端是使用root用户
读写/data目录里的内容的,假如在客户端换成普通用户呢?这里我明确的告诉大家,对于上述极简
示例中,客户端使用普通用户,只能读,不能写,示例如下:

[oldboy@web-client ~]$ cat /data/f4.txt 
123456
[root@web-client ~]# su - oldboy
[oldboy@web-client ~]$ echo "hello" >> /data/f4.txt
-bash: /data/f4.txt: Permission denied

到这里,相信读者已经开始思考了,我们先抛开NFS,就我们已有的Linux文件系统权限的知识先分析
一下,在上面的极简案例中我们设置了这样一条:

[root@nfs-server ~]# chown -R nfsnobody:nfsnobody /data

这是什么鬼呢,首先chown是更改目录所有者和所属组,-R参数是递归修改子目录和子文件,这是我们
已有的知识,那nfsnobody是什么鬼,让我告诉你,这个用户是我们安装nfs-utils自动为我们创建
的,这个软件包还为我们创建了一些其它用户,大家可以检查/etc/passwd看到,不过我们只关
心nfsnobody这个用户,可以id命令先看下这个用户的信息:

[root@nfs-server ~]# id nfsnobody
uid=65534(nfsnobody) gid=65534(nfsnobody) groups=65534(nfsnobody)

这里的名字和ID都是固定的,只要安装了nfs-utils包,该用户就会自动被创建。现在我们在服务端
检查一下/data目录的属性:

[root@nfs-server ~]# ls -ld /data
drwxr-xr-x 2 nfsnobody nfsnobody 62 Sep  8 21:12 /data

可以看到,在服务端本地,/data目录的所有者和所述组都是nfsnobody,那我们在服务端建立一个
文件,观察下,这个文件的权限又是什么:

[root@nfs-server ~]# touch /data/f5.txt
[root@nfs-server ~]# ls -l /data/f5.txt
-rw-r--r-- 1 root root 0 Sep  8 21:50 /data/f5.txt

可以看到符合我们的预期f5.txt的所有者和所属组都是root用户。那么我们换到客户端,看一下在
服务端/data目录是什么权限:

[root@web-client ~]# umount /data
[root@web-client ~]# ls -ld /data
drwxr-xr-x 2 root root 6 Sep  6 12:24 /data
[root@web-client ~]# mount -t nfs 172.16.1.31:/data /data
[root@web-client ~]# ls -ld /data
drwxr-xr-x 2 nfsnobody nfsnobody 90 Sep  8 21:50 /data

可以看到,未挂载远端共享的/data目录,查看本地的/data目录其所有者和所属组都是root,而
挂载到远端/data目录后,所有者和所属组和远端/data目录保持一致,是nfsnobody,符合预期。
现在我们在客户端/data目录里创建一个文件,看一下其权限:

[root@web-client ~]# touch /data/f6.txt
[root@web-client ~]# ls -l /data/f6.txt
-rw-r--r-- 1 nfsnobody nfsnobody 0 Sep  8 21:50 /data/f6.txt

问题出现了,我们明明用的是root用户,但是创建出来的文件其所有者和所述组确是nfsnobody,这是
怎么一回事,不用说这肯定是服务端nfs的配置文件在起作用。

稳住,我知道大家看到这里,仍是云里雾里,似乎不知所云,相信我,本节看完,一切豁然开朗。

我们再看一下在极简案例中,我们服务端的配置文件/etc/exports

[root@nfs-server ~]# cat /etc/exports
/data *(rw)

这里的/data就是服务器要共享的目录名,*(星号)表示共享给所有机器使用,rw表示客户端对该目录
具有读写权限。实际上小括号里可以配置多个参数,我们这里虽然只写了一个参数,但是nfs服务默认
就有一些预设参数,即默认值,这些默认参数到底有哪些呢,可以在/var/lib/nfs/etab中看到:

NFS

上面的内容都是在一行的,黄色部分是我们直接配的,小括号里其它参数则都是nfs的默认值,我们
重点关注的是里面的红色默认参数:

anonuid=65534,anongid=65534
    正好是我们的nfsnobody用户的uid和gid
        
root_squash
    直接翻译过来是压缩root用户,这是针对客户端来说的,含义是当客户端使用root用户
    操作/data目录里的文件时,将其"压缩"(转换成)anonuid和anongid对应的用户,在
    极简案例中就是nfsnobody用户
    
no_all_squash
    也是针对客户端来说的,含义就是,客户端不管使用什么用户身份操作,都保持其原始身
    份不变,即原始是什么用户身份映射到服务端还是什么身份。在我们的极简案例中,root
    用户除外,其映射到服务端会被转换成nfsnobody身份,英文我们默认参数单独定义了
    root_squash来规定root的映射规则。
    
    该参数不常用,正如我们上文举例那样,客户端假如使用的不是root用户,比如客户端
    使用的是oldboy普通用户,/data目录的所有者是nfsnobody,那么oldboy对于/data
    目录来说,就是其它人,即只具有读的权限,可见这种默认的配置,服务端已经配置了
    /data目录开放读写权限给客户端,但是客户端必须使用root用户操作/data,这样才
    能映射为服务端的nfsnobody身份,也就是对/data目录具有了读写权限。

    读者可能会想,我在客户端就是使用nfsnobody用户登录,来操作/data目录,这样不就也  
    可以执行写操作了吗,不行的。nfsnobody是虚拟用户,不允许登录。

那么问题来了,如果我们把/etc/exports配置成/data *(rw),其含义就是其它客户端机器必须
使用root用户操作/data,才能正常读写远程/data目录。我们的需求是,服务端不管使用什么用户
操作远程/data目录,我们都给映射到服务器这边的nfsnobody用户,这样/data目录里清一色,
所有者和所属组都是nfsnobody,看起来清爽的同时也便于我们维护,那么如何修改/etc/exports
才能实现我们的需求呢,请看下一节。

NFS服务端配置

NFS服务器端的配置参数在/etc/exports。该配置文件说明了这台NFS服务器有哪些目录共享
给客户端使用,客户端对这些目录具有什么操作权限等。可以使用man exports查看参数配置
帮助。

简单示例如下:

[root@nfs-server ~]# cat /etc/exports
/data 172.16.1.7(rw)

上面的配置参数表示,服务器把/data目录共享给172.16.1.7这台机器使用,客户端具有的权限是
读和写(rw)

通过示例可以看到,NFS服务器端/etc/exports配置参数,基本格式如下:

NFS共享目录 客户端地址1(参数1,参数2, ...) 客户端地址2(参数1,参数2, ...)

客户端地址的表示方法

星号(*),表示所有服务器。
172.16.1.7,表示这一台机器。 172.16.1.0/24,该配置最常用,表示同一个局域网内的所有机器(★★★) web-client,这是直接使用主机名标识客户端地址,需要做DNS解析,原理还是找到主机名对应的
IP地址。

/etc/exports参数

NFS共享参数

作用

rw

读写权限

ro

只读权限(read-only)

root_squash

默认值,客户端root用户映射为服务端指定用户

no_root_squash

客户端root用户映射为服务端root用户

all_squash

客户端所有用户映射为服务端指定用户

no_all_squash

默认值,客户端什么用户映射到服务端还是什么用户

sync

默认值,写入数据时,硬盘与内存保持同步

async

写入数据时,先写入内存,再写入硬盘

anonuid

指定映射用户的uid,默认值65534(nfsnobody)

anongid

指定映射用户的gid,默认值65534(nfsnobody)

指定用户即anonuid和anongid所指定的用户。 sync和async一般认为异步性能高,同步数据安全,然实际情况区别不大,使用默认值即可。
no_root_squash,该参数对于服务端比较危险,随便在局域网内找一台机器使用root登录,
操作远程/data目录,映射到NFS服务端这边也是root用户,权限过大。 上面表格列出了10个参数,其中前4对,都是2选一,最后2个参数一般同时指定。

现在我们解决,在NFS文件访问权限那一节里留下的问题,我们可以使用下述配置:

[root@nfs-server ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash)

上面这个配置是比较常用的配置,同一局域网内的所有客户端,操作远程/data目录时,都会被映射
为服务端上的nfsnobody用户。

/etc/exports里面的配置是可以用#,注释掉的

/etc/exports生效

修改完毕/etc/exports之后,有两种方式可以使其生效:

1 重启nfs-server服务

[root@nfs-server nfs]# systemctl restart nfs-server

2 重载/etc/exports配置文件

[root@nfs-server nfs]# exportfs -arv
exporting 172.16.1.0/24:/data

a(all 所有),r(reexport 重新),v(verbose 详细信息),这三个参数一般连用表示从新加载
/etc/exports文件里所有的配置,应用新的配置。

还可以使用exportfs -auv,u(unexport 取消),表示取消该台NFS服务器上共享的所有目录。
更多exportfs用法,请参考man exportfs

重启服务比较强硬,而重载服务则比较温柔,平滑一些。什么,重启服务器是配置参数生效?别闹。

3 服务端查看配置参数是否修改成功(/var/lib/nfs/etab)

比如我们把服务端的/etc/exports配置成如下内容:

[root@nfs-server ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash)
[root@nfs-server nfs]# systemctl restart nfs-server

此时可以检查下/var/lib/nfs/etab,该文件里的内容,是否已经成功变更为我们所修改的内容,
当然此文件里还包含默认共享参数:

NFS

可以看到我们的修改已经生效。

4 客户端的操作(非必须)

如果客户端已经事先知道服务端修改了共享参数,可以重新挂载远程目录:

[root@web-client ~]# umount /data
[root@web-client ~]# mount -t nfs 172.16.1.31:/data /data

上述操作不是必须的,服务端只要修改了共享参数,则客户端立即生效,比如刚开始共享为读写权限,
随后修改为只读权限,那么客户端即刻就无法在向共享目录里写入数据,这很好理解客户端的操作最终
都是通过rpcbind远程映射到服务端,然后服务端再进一步通过NFS相关服务向磁盘中写入数据的。

只不过在有些情况下,服务端修改了配置参数而客户端没有重新挂载,这时第1次操作远端目录时,会
等待一会。

创建共享目录

服务端除了启动rpcbind和nfs-server服务,配置/etc/exports之外,另外一个重要的步骤就是
要创建共享目录了,这是必须的,要共享这个目录而这个目录没有,那肯定要报错的。在我们的极
简单案例中,我们执行了如下两条命令:

[root@nfs-server ~]# mkdir /data
[root@nfs-server ~]# chown -R nfsnobody:nfsnobody /data

这个时候我们就知道,为什么需要把/data目录的所有者和所属组改成nfsnobody,该用户是安装
nfs-utils包自动为我们创建的,它的uid和gid都是65534,而/etc/exports里anonuid和
anongid默认的值正是65534,所对应的就是nfsnobody用户,说白了就是NFS为了我们方便,当我
们并不关心/data的所有者是谁时,给它指定成nfsnobody即可。

现在情况有变,我们不想让/data目录的所有者和所属组都是nfsnobody,想指定一个id和名字都
固定的其它用户,比如uid和gid都是666的www用户,这时我们对客户端和服务端都需要进行操作:

1 服务端操作

[root@nfs-server ~]# groupadd -g 666 www
[root@nfs-server ~]# useradd -u 666 -g 666 -s /sbin/nologin -M www
[root@nfs-server ~]# id www
uid=666(www) gid=666(www) groups=666(www)
[root@nfs-server ~]# vim /etc/exports
[root@nfs-server ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
[root@nfs-server ~]# exportfs -arv
exporting 172.16.1.0/24:/data
[root@nfs-server ~]# chown -R www:www /data
[root@nfs-server ~]# ls -ld /data
drwxr-xr-x 2 www www 90 Sep  8 23:11 /data

把www用户建立成虚拟用户不是必须的,只不过为了安全考虑,默认的nfsnobody就是虚拟用户,其
无法登录系统。uid和gid都设置成固定值是为了便于管理。

2 客户端操作

[root@web-client ~]# groupadd -g 666 www
[root@web-client ~]# useradd -u 666 -g 666 -s /sbin/nologin -M www
[root@nfs-web-client ~]# id www
uid=666(www) gid=666(www) groups=666(www)

客户端建立同ID,同名称的www用户不是必须的,但是如果我们不建立,那么在客户端查看/data目录
下的属性时,会像下面这样:

[root@web-client ~]# ls -l /data
total 12
-rw-r--r-- 1 666 666 14 Sep  8 12:27 f1.txt
-rw-r--r-- 1 666 666  7 Sep  8 09:27 f2.txt
-rw-r--r-- 1 666 666  0 Sep  7 19:28 f3.txt

那么多666?一点都不顺,而是老别扭了,因此我们需要在客户端这边也建立同ID,同名称的用户,
需要注意,Linux系统是根据ID识别用户的,客户端这边最好不要有其它用户id是666,那就太乱
了。创建好同样的ID后,我再看一下属性:

[root@web-client ~]# ls -l /data
total 12
-rw-r--r-- 1 www www 14 Sep  8 12:27 f1.txt
-rw-r--r-- 1 www www  7 Sep  8 09:27 f2.txt
-rw-r--r-- 1 www www  0 Sep  7 19:28 f3.txt

这样才符合我们的认知直觉。

NFS服务端配置小结

现在,我们再看一下极简案例中配置NFS服务端配置的步骤(稍作修改):

[root@nfs-server ~]# yum install nfs-utils -y
[root@nfs-server ~]# systemctl restart rpcbind
[root@nfs-server ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash)
[root@nfs-server ~]# mkdir /data
[root@nfs-server ~]# chown -R nfsnobody:nfsnobody /data
[root@nfs-server ~]# systemctl restart nfs-server

如果对上面的每一行都清楚其作用的话,那么恭喜你也感谢你,说明NFS服务端配置套路已基本掌握,
也说明我上面的内容写的不错哈。不过现在记得,未必以后也记得,我在这里也总结下:

  1. rpcbind服务必须先启动,然后再启动nfs-server服务,否则NFS服务搭建失败。
  2. 修改服务端配置文件后,需要重启服务或重载配置文件使其生效。
  3. 要共享的目录其所有者和所属组必须是anonuid和anongid指定的用户。

NFS客户端配置

服务端已经配置完毕,现在就等着客户端使用了。NFS服务是rpcbind服务进行远程通信的,显然
客户端这边同样需要rpcbind服务,不过为了方便我们在客户端也直接装上nfs-utils包,不过只
需启动rpcbind服务即可。

[root@web-client ~]# yum install nfs-utils -y
[root@nfs-server ~]# systemctl restart rpcbind

另外如果服务端共享目录的所有者和所属组不是nfsnobody,在客户端最好也创建一个同ID,用名称
的用户,创建方法见上文。

查看远端共享目录

rpcbind服务已经启动完毕,现在可以挂载远端目录了,但是且慢,如果我们不知道远端共享的是什么
目录呢,这时我们需要看一下远端共享了哪些目录,此时我们可以使用下面的命令:

[root@web-client ~]# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24

完整语法如下:

showmount [ --exports ] [ --help ] [ --version ] [ host ] -e or --exports,显示远程服务器,可供使用的挂载列表

showmount在客户端和服务端都可以使用,只要安装了nfs-utils包,就有该命令,基本上用法就上面
一种,可以看到172.16.1.31这台NFS服务器共享了其/data目录给大家使用。大家可能会感觉上面给
出的共享参数信息,有点少啊,比如不知道是否对该目录有写入权限,如果看到的信息类似与在服务
cat /etc/exports那样,似乎更好一些,但是本人多方查找资料,基本确定没有办法在客户端
看到共享参数权限的详细信息,要想知道自己是否对某个共享目录具有写入权限,只能靠人工测试,
如果没有写入权限,会得到如下所示的提示:

[root@web-client ~]# echo '123' > /data/f1.txt
bash: /data/f1.txt: Read-only file system

showmount命令不加参数直接回车,无任何效果并且Xshell会卡住,CTRL+C无效,只能等待。

挂载共享目录

知道是哪个远端机器,共享的什么目录,就可以开始挂载了:

[root@web-client ~]# mkdir /data
[root@web-client ~]# mount -t nfs 172.16.1.31:/data /data

注意远端的/data目录不一定必须挂载在本地的/data目录,其它目录也一样可以。挂载完毕之后, 可以使用df -h命令查看一下:

NFS

这样挂载之后,我们就可以正常在本地/data目录里使用远程/data目录里的文件了,本地和远端
操作的都是同一块硬盘,对客户端来说远程NFS服务器仿佛是透明的。

卸载共享目录

回顾一下正常挂载的语法:mount -t type device dir
正常卸载的语法:umount dir

完整卸载的语法:
umount [-dflnrv] {dir|device}... ,其中-lf参数比较常用,下面分别进行介绍。

-l, --lazy 直接翻译是懒惰卸载,可以理解为平滑卸载。请看下面的示例:

[root@web-client data]# pwd
/data
[root@web-client data]# umount /data
umount.nfs4: /data: device is busy

我们知道这种情况无法卸载的原因显而易见,就是我们当前处于/data目录,从而提示设备 被占用,导致我们无法卸载。但有时提示设备被占用,我们也不知道到底是哪个程序占用了 /data目录里的文件,或者我们不关注/data是不是还有文件正在使用,就是要直接卸载 /data,此时就可以添加-l,如下:

[root@web-client data]# umount -l /data

此时我们使用df -h,已经看不到/data目录的挂载信息了,但是/data目录并没有被立即 卸载,系统会自动判断当我们已经没有程序占用/data目录时,自动卸载/data目录

-f, --force 强制卸载,通常用在NFS系统上,经常配合-l参数使用。比如当前系统/data目录是NFS 远程共享的,若果远程的NFS服务器,突然故障,此时我们无法访问/data目录,并且正常 卸载/data目录也无法卸载,则可以使用:

[root@web-client /]# umount -lf /data

强制进行卸载。

参考资料

http://cn.linux.vbird.org/linux_server/0330nfs.php#exec http://docs.etiantian.org/15323330999008.html#toc_5 https://en.wikipedia.org/wiki/Network_File_System https://en.wikipedia.org/wiki/Open_Network_Computing_Remote_Procedure_Call 跟老男孩学Linux运维-Web集群实战-老男孩著

作者:阿胜4K 出处:https://www.cnblogs.com/asheng2016/p/9613065.html

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这