私活利器,docker快速部署node.js应用

http://cnodejs.org/topic/53f494d9bbdaa79d519c9a4a

最近研究了几天docker的快速部署,感觉很有新意,非常轻量级和方便,打算在公司推广一下,解放运维,省得每次部署一台新服务器都去跑安装脚本了,对于我们开发人员也是好事情,无需写太多重复的部署文档,直接将docker的images丢上服务器就可以运行了。

可能还有一些同学不了解docker这个项目,docker是由go语言编写的,一个快速部署的轻量级虚拟技术项目,他允许开发人员将自己的程序和运行环境一起打包,制作成一个docker的image(镜像),这样部署到服务器上,也只需要下载这个image就可以将程序跑起来,免去每次都安装各种依赖和环境的麻烦,还能够做到应用程序之间的隔离,因为我们公司部署的python程序,这样一来我也省去了每次都到新服务器配置 vitualenv了。

官网地址:http://www.docker.com/

如此看来docker非常适合做小巧的外包项目,免去每次都为客户配置一遍运行环境,费时费力。

一、安装: 安装很简单,直接进入下载页面,根据自己的操作系统下载相对应的安装包即可,下面说一下windows安装:

下载地址:https://docs.docker.com/installation/windows/

在安装docker时,会附带安装git和VirtualBox,所以可能安装时间稍微长一些,安装完毕重启系统,以管理员身份进入命令行,就可以使用进入linux虚拟机命令 “boot2docker” ,由于docker目前的镜像只针对linux,所以windows下面必须安装虚拟机才能使用。

第一次使用boot2docker start,会出现错误:

    Failed to get machine "boot2docker-vm": machine does not exist

没关系,这是因为没有boot2docker iso的镜像所致,执行:

    $ boot2docker init

就可以初始化镜像,耐心等待下载并安装完毕后,我们继续执行开启虚拟机。

    $ boot2docker start 

在windows下是无法直接使用cmd窗口来操作linux系统的,所以我们需要进入linux虚拟机来操作docker,执行:

    $ boot2docker ssh

就可以进入linux虚拟机,如果要退出并关闭虚拟机,执行如下命令:

    $ exit$ boot2docker stop

调试时查看虚拟机ip地址,后面部署测试环境会用到:

    $ boot2docker ip192.168.59.103

我们可以通过ssh的ip地址192.168.59.103,用户名 docker,密码 tcuser,登录到虚拟机中去。

如果不幸长时间无法init成功,说明镜像被GFW挡住了,手动去github上下载镜像,地址为:

https://github.com/boot2docker/boot2docker/releases

如果还是无法下载成功,我是好心人,把1.1.2版本的boot2docker.iso镜像丢到了百度云上:

http://pan.baidu.com/s/1c01qieG

下载完毕之后放到目录:

    C:\Users\你的用户名\.boot2docker\boot2docker.iso

然后再执行

    $ boot2docker init

二、下载镜像,安装环境 我们先执行如下命令,启动虚拟机:

    $ boot2docker start2014/08/18 21:22:41 Waiting for VM to be started... ........... 2014/08/18 21:23:21 Started. 2014/08/18 21:23:21 Docker client does not run on Windows for now. Please use 2014/08/18 21:23:21 "boot2docker" ssh 2014/08/18 21:23:21 to SSH into the VM instead.

如果我们的物理机内存低于4G,那么跑这个boot2docker可能需要手动设置内存占用大小:

    $ boot2docker start -m=512

我们利用命令就可以进入linux虚拟机了

    $ boot2docker ssh ##        .## ## ##       == ## ## ## ## === /""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\______/ _ _ ____ _ _ | |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| boot2docker: 1.1.2 master : 740106c - Thu Jul 24 03:24:10 UTC 2014

执行 docker 命令,会有一个命令列表,里面列出了所有 docker 支持的功能,列表如下:

    Commands:attach    Attach to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes ... ...

下面会对一些常用的命令进行示例说明,我们可以通过如下命令,先查找centos的镜像,并把他下载下来

    $ docker search centos #查找centos名字的镜像$ docker pull centos #下载官方纯净版本的centos镜像

在调用search命令时,你会看到有好多centos包,他们都是这样的<username>/<image_name>,这些不在根目录的镜像都是非官方的,是其他用户提交到docker hub上去的,耐心等待片刻我们就可以将centos的镜像拉下来了。

如果脸黑,镜像又不幸被墙,那么试试加上下面的hosts:

    54.234.135.251 get.docker.io 54.234.135.251 cdn-registry-1.docker.io

成功下载好centos镜像之后,我们可以利用如下命令来查看镜像列表:

    $ docker imagesREPOSITORY          TAG                 IMAGE ID            CREATEDVIRTUAL SIZEcentos              centos6             b1bd49907d55        2 weeks ago212.5 MB centos centos7 b157b77b1a65 2 weeks ago 243.7 MB centos latest b157b77b1a65 2 weeks ago 243.7 MB

接下来我们就利用centos7这个镜像输出一段 hello world

    $ docker run b15 /bin/echo 'Hello world' Hello world

注意这里的 b15,他表示centos7这个images的id,不用全部打全,只要保证输入的id前几位能找到唯一镜像即可,这点很赞。 稍微复杂一点的例子:

    $ docker run  -i -d -t b15 /bin/sh -c "while true; do echo hello world; sleep 1; done"

-i表示同步container的stdin,-t表示同步container的输出,-d表示deamon,以后台启动这个container,执行这个container是永远不会停止的,每一秒钟都会输出hello world。

至于什么是container,container和image的关系我们下一段再说,列出镜像的历史:

    $docker history image_name

三、安装环境 在开始第三段介绍之前,有必要说几个利用windows cmd窗口的小技巧。

1、如果想要使用标记选中功能,你会发现,当我们进入 boot2docker ssh 之后,鼠标对窗口的右键是无效的,所以想要利用标记选中窗口内的文字得这么弄:“点击左上角图标->编辑->标记”,这样就可以使用标记了

2、如果从其他地方复制了命令,但是窗口没有右键无法粘贴怎么办?用和1相同的办法:“点击左上角图标->编辑->粘贴”。

3、坑爹的windws如果命令太长,在boot2docker ssh里换行会错位的,在“点击左上角图标->属性->布局->屏幕缓冲区大小和窗口大小”的数值,保证长的命令也在一行内就没有问题了,注意要重启cmd窗口。

接下来我们简单说明一下image和container的关系,image顾名思义就是镜像的意思,我们把他理解为一个执行环境(env),当我们执行了docker run命令之后,dock就会根据当前的image创建一个新的container,container更像是一个操作或者程序运行的一个沙箱,他们互相独立,但是都运行在image创建的执行环境之上,根据上一段我们执行了2个run的任务,也就创建了2个独立的container,我们通过命令

    $ docker ps #查看当前运行的container$ docker ps -a #查看所有的container CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d1eca89869d0 centos:centos7 /bin/sh -c 'while tr 13 minutes ago Exited (0) 7 minutes ago distracted_mcclintock 0b71024c8a95 centos:centos7 /bin/sh -c 'while tr 15 minutes ago Exited (0) 7 minutes ago pensive_meitner 79a488c9cfb6 centos:centos7 console 22 minutes ago sick_babbage 06f43c19d10a centos:centos7 /bin/echo 'Hello wor 25 minutes ago Exited (0) 25 minutes ago berserk_einstein

我们可以分别利用命令对image和container进行删除

    $ docker rm #删除container$ docker rmi #删除image $ docker rm `docker ps -a -q` #删除所有容器

这样执行一次run就创建一个container,势必会造成大量的无用的container,可能我不需要持久化保存container,如果在docker run命令加上 --rm=true 选项,那当这个container执行完毕,将自动自己删除,保证了container数量不会泛滥增长。

我们之前下载纯净版centos7是没有任何第三方软件的,包括wget,ping等命令都要通过yum工具来重新安装,我们当然不想每次都重新安装这些东西,我不仅希望要把一些常用的库安装到的image中去,同时还希望把程序运行的环境也安装进去,所以image更像是一个系统的模版。

你会发现,当你执行如下命令,wget命令时安装成功了,但是当你下次执行wget命令时,又会报错,说找不到这个命令,到底是怎么回事呢?

    $ docker run -t b15 yum install -y wget #通过yum工具安装wget命令 #安装完毕后,执行wget会报没有这个命令 $ docker run -t b15 wget http://www.baidu.com 2014/08/18 15:42:19 exec: "wget": executable file not found in $PATH

为什么会出现这个问题呢?答案就是我们上面所说的那样,每次执行docker run都会去独立的创建一个新的container来执行程序,所以我们必须手动把这些对container的更改提交成一个新的image,才能够依据这个image执行wget操作。

我们先把当前所有的container都删除,然后直接登录到container的bash命令窗口中去,免得每次都去输入docker run了

    $ docker run -t -i b15 /bin/bash bash-4.2#

这样我们进入了一个新的container,依据centos7作为模板,我们将要在其上面安装wget工具,直接执行

    $ yum install -y wget

安装完毕之后,我们执行exit退出container 输入docker ps -a 我们找到刚才安装过wget工具的container ID,我们要把这个container重新做成一个新的image模版,这个模版将带wget命令。

    $ docker ps -aCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES26cc82ad29af centos:centos7 /bin/bash 3 minutes ago Exited (0) 5 seconds ago desperate_mccarthy

我们执行如下命令,将一个安装过软件的container提交为一个image

    $ docker commit 26  wget-centos7 60cd26c6ca1e753bf77aa913ed7b826767a678b75f6dd8421353f6c0899d3e5e

我们查看当前image镜像的列表:

    wget-centos7        latest              60cd26c6ca1e 37 seconds ago 304.6 MB centos centos6 b1bd49907d55 2 weeks ago 212.5 MB centos centos7 b157b77b1a65 2 weeks ago 243.7 MB centos latest b157b77b1a65 2 weeks ago 243.7 MB

你会发现多了一行我们刚才提交的 wget-centos7 的image镜像记录,现在我们执行这个镜像的wget命令,看看会不会报错

    $ docker run -t -i --rm=true 60 wget http://www.baidu.com --2014-08-18 15:54:55-- http://www.baidu.com/ Resolving www.baidu.com (www.baidu.com)... 180.97.33.108, 180.97.33.107 Connecting to www.baidu.com (www.baidu.com)|180.97.33.108|:80... connected. HTTP request sent, awaiting response... 200 OK

执行完毕后,docker自动删除这个container,并且至今报错的wget命令无法找到也不会出错了。

第二种安装环境的办法,类似脚本安装,我们预先录入好一系列安装脚本,可以让docker帮我们依次执行这些安装脚本,然后生成image,例如有安装脚本Dockerfile:

    # This is a commentFROM centosMAINTAINER doublespout <doublespout[@gmail](/user/gmail).com> RUN yum install -y wget

我们执行如下命令进行创建images

    $ mkdir wget$ cd wget$ vi Dockerfile #将上面内容复制进去 $ docker build -t="doublespout/wget" ./ #将看到安装脚本的执行输出,安装完成后,执行 docker images 就可以看到我们刚才创建的镜像了 docker images

container 和 host 文件互相拷贝:

1、从container往host拷贝文件:

    docker cp <container_id>:/root/hello.txt .

2、从host往container里拷贝文件,比较麻烦一点,首先停止Contaitner(当然不停止也能拷贝)

    docker stop <container_name_or_ID>

然后执行拷贝操作,执行完成之后就能看到Contaitner里有这个文件拉

    #执行命令找到程序pidContainerID=$(docker inspect --format {{.Id}} <container_name_or_ID>) cp /tmp/tmp.txt /var/lib/docker/aufs/mnt/<ContainerID>/tmp/

四、发布应用程序 我们根据上一段的步骤,手动将node.js环境装好container并且发布成image,并保存"app.js"文件到"/var/nodejs/app.js",文件内容为:

    var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337); //注意这边不能和官网示例那样监听127.0.0.1 console.log('Server running at http://0.0.0.0:1337/');

执行如下命令,运行container:

    $ docker run -d -i -p --name=nodeapp 1337:1337 fa node /var/nodejs/app.js #32bac9ed8ba055c935bd641d23097a36a573a243ee942358fd74dc4140308bc6

其中fa是我创建的镜像id,这个值因人而异,name参数是给这个container取名字,必须是唯一的。

-p参数就是类似端口映射的功能,将主机的端口1337映射到contianer的1337端口,我们可以运行 docker ps,查看正在运行的container,打开浏览器,就能够看到 hello world了。

用同样的方法就可以将我们开发好的应用快速部署到生产服务器上去了。如果在docker run命令需要设置cpu的支持数和权重值可以这样:

     -c, --cpu-shares=0 CPU shares (relative weight) --cpuset="" CPUs in which to allow execution (0-3, 0,1)

另外一个小敲门,如果我想要进入一个在运行中的docker container时,可以使用 docker attach,连上这个container的输入和输出。

五、将多个 container 连接起来

我现在先下载一个redis数据库image,这也是以后做项目的常规用法,数据库单独用一个image,程序一个image,利用docker的link属性将他们连接起来。

    $ docker pull redis #下载官方的redis镜像,耐心等待一段时间

接着我们执行命令启动redis镜像到一个container,开启redis-server持久化服务

    $ docker run --name redis-server -d redis redis-server --appendonly yes

然后我们再启动一个redis镜像的container作为客户端连接它

    $ docker run -it --link redis-server:redis --rm redis /bin/bash redis[@7441b8880e4e](/user/7441b8880e4e):/data$ env #想要知道当前我们在主机还是container,注意$前面的host和name REDIS_PORT_6379_TCP_PROTO=tcp HOSTNAME=7441b8880e4e TERM=xterm REDIS_NAME=/boring_perlman/redis REDIS_PORT_6379_TCP_ADDR=172.17.0.34 #redis服务器ip REDIS_PORT_6379_TCP_PORT=6379 #redis服务器端口 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/data REDIS_PORT_6379_TCP=tcp://172.17.0.34:6379 SHLVL=1 REDIS_PORT=tcp://172.17.0.34:6379 HOME=/ _=/usr/bin/env $ redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT" 172.17.0.34:6379> set a 1 #成功连入redis数据库服务器 OK 172.17.0.34:6379> get a "1" 172.17.0.34:6379>

通过这样的方法,我们就可以将发布的应用程序和数据库分开,单独进行管理,以后对数据库进行升级或者对程序进行调整两者都没有冲突,系统环境变量我们可以通过程序的os模块来获得。

六、文件卷标加载 比如我们想要一个日志文件保存目录,如果直接写入container,那样image升级之后,日志文件处理就比较麻烦了,所以就需要将主机的文件卷标挂载到container中去,挂载方法如下:

    $ docker run --rm=true -i -t --name=ls-volume -v /etc/:/opt/etc/ centos ls /opt/etc boot2docker hostname ld.so.conf passwd- securetty sysconfig default hosts mke2fs.conf pcmcia services sysctl.conf fstab hosts.allow modprobe.conf profile shadow udev group hosts.deny motd profile.d shadow- version group- init.d mtab protocols shells gshadow inittab netconfig rc.d skel gshadow- issue nsswitch.conf resolv.conf ssl host.conf ld.so.cache passwd rpc sudoers

如果想要挂载后的文件是只读,需要在这样挂载:

    -v /etc/:/opt/etc/:ro #read only

我们也可以挂载其他container中的文件系统,需要用到 -volumes-from 参数,我们先创建一个container,他共享/var/目录给其他container。

    $ docker run -d -i -t -p 1337:1337 --name nodedev -v /var/ fa node /var/nodejs/app.js

然后我们启动一个ls-var的container来挂载nodedev共享的目录:

    $ docker run --rm=true -i -t --volumes-from nodedev --name=aaa1 centos ls /var adm db games kerberos local log nis opt run tmp yp cache empty gopher lib lock mail nodejs preserve spool var

我们打印var目录,会发现多了一个nodejs的目录,就是从nodedev中的container挂载过来的。其实我们挂载其他container的路径都是在根目录上的。

七、发布到docker hub上去

我们做完镜像,就需要将镜像发布到docker hub上,供服务器下载然后运行,这类似git仓库,将自己开发的东西丢到云服务器上,然后自己在其他机器或者其他开发者可以下载镜像,并且从这个镜像开始运行程序或者再进行2次制作镜像。

我们需要先登录docker帐号,执行:

    $ docker login #输入你在docker官网注册的帐号和密码就可以登录了$ docker push <用户名>/<镜像名> #将你制作的镜像提交到docker hub上

非官方不允许直接提交根目录镜像,所以必须以<用户名>/<镜像名>这样的方式提交,比如 doublespout/dev 这样

八、总结

docker快速部署介绍完毕了,总结一下,要创建一个简单项目使用的步骤: 1、安装配置docker

2、pull镜像,安装程序执行环境

3、pull数据库镜像

4、开发程序

5、push 程序的镜像

6、服务器安装配置docker

7、运行数据库镜像

8、运行程序镜像,并且把数据库镜像link进来,并且挂载主机的日志目录或其他上传目录。

使用了docker以后,环境配置只需一次,免去了开发部署一套,测试部署一套,生产又部署一套的麻烦,以后程序搬家也是非常简单。

最后分享一个小敲门,如何像使用linux虚拟机那样运行一个container,比如我我们想要直接登录container执行多个任务,又不想直接借助 docker run 命令,以后我们还想登录到这个container来查看运行情况,比如执行top,ps -aux命令等等。

   $ docker run -d -i -t -p 1337:1337 fa /bin/bash $ docker attach 58 bash-4.2#

这样我们就可以通过进入container来调试程序了。但是一旦执行ctrl+d或者exit,container就将退出,这个方法也只适用于开发调试的时候。 最后请跳出 container 是一个小的vps的概念,详见另一篇文章.

不要用ssh连接直接到你的container 常用的Dockerfile命令示例

74 回复

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

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

相关文章

HDFS HA与QJM(Quorum Journal Manager)介绍及官网内容整理

问题导读1.HDFS HA与QJM解决了什么问题&#xff1f; 2.HDFS HA与QJM区别是什么&#xff1f; 3.在HA&#xff08;两个namenode&#xff09;架构下&#xff0c;如何访问hdfs文件&#xff1f;【使用QJM构建HDFS HA架构(2.2)】本文主要介绍HDFS HA特性&#xff0c;以及如何使用QJM(…

#时间预测算法_【时间序列】时序预测竞赛之异常检测算法综述

本文将介绍在时间序列预测相关问题中常见的异常检测算法&#xff0c;可以很大程度上帮助改善最终预测效果。异常分类时间序列的异常检测问题通常表示为相对于某些标准信号或常见信号的离群点。虽然有很多的异常类型&#xff0c;但是我们只关注业务角度中最重要的类型&#xff0…

监测利器cacti服务安装

1、Cacti原理及概述1Cacti是一款使用PHP语言开发的性能与流量监测工具。监测的对象可以是linux也可以是windows也可以是路由器交换机等网络设备主要基于SNMPsimple network managerprotocol简单网络管理协议来搜集cpu占用内存使用运行进程数磁盘空间网卡流量等各种网络数据。2实…

linux c之解决array subscript is not integer和AF_NET not undeclared

1、array subscript is not integer 我一开始写的代码是这样的写的 buf[strlen[buf] - 1] \0; 很明显写错了&#xff0c;以后不要再犯这样的错误了&#xff0c;切记 buf[strlen(buf) - 1] \0; 2、AF_NET not undeclared 这是我写的代码 inet.pton(AF_NET, buf 6, &add…

C#中的类型转换

前几篇文章中经常说到强制类型转换&#xff0c;就是可以将派生类对象强制转换为基类对象的做法或者通过as运算符进行的转换。今天我们就来一起简单了解复习下在C#中都有哪些类型的转换。要理解转换很容易&#xff0c;日常的开发编码过程中&#xff0c;由于变量类型的不同我们可…

Excel 用于批量把单元格设置为文本格式保存的数字的宏

首先把所有的数字录入&#xff08;或者导出为&#xff09;井号数字的格式&#xff0c;比如“#3333333323424234234234”&#xff0c;然后运行下面的宏&#xff1a; Sub Num2Text()If Not TypeOf Application.Selection Is Range ThenMsgBox "You must select cells!"…

ACM题解系列之一:刘汝佳:《算法竞赛入门经典》(第2版)

题是书中的题&#xff0c;解法参照了书中的解法&#xff0c;不少解法都做了简化和改进。 做程序&#xff0c;就要努力做到自己的程序是最好的&#xff01; 第3章例题 POJ1488 UVA272 UVALive5381 TEX Quote【输入输出】 POJ2538 ZOJ1884 UVA10082 WERTYU【输入输出】 HDU1318 P…

linux之快速过滤文本的关键字以及快速过滤目录下的关键字

1、快速过过滤文本的关键字 cat file | grep 关键字 比如Android日志文件很长&#xff0c;需要过滤Exception,就可以用这个办法&#xff0c;如下图 2、快速过滤目录下的关键字 grep -r 关键字 比如我们在linux上看目录下哪些关键字段&#xff0c;好像开发工具里面的 find usag…

hadoop使用

2019独角兽企业重金招聘Python工程师标准>>> 框架简介 Hadoop使用主/从&#xff08;Master/Slave&#xff09;架构&#xff0c;主要角色有NameNode&#xff0c;DataNode&#xff0c;secondary NameNode&#xff0c;JobTracker&#xff0c;TaskTracker组成。 其中Nam…

bigint hive java类型_详解Apache Hudi如何配置各种类型分区

1. 引入Apache Hudi支持多种分区方式数据集&#xff0c;如多级分区、单分区、时间日期分区、无分区数据集等&#xff0c;用户可根据实际需求选择合适的分区方式&#xff0c;下面来详细了解Hudi如何配置何种类型分区。2. 分区处理为说明Hudi对不同分区类型的处理&#xff0c;假定…

C#中的命名空间和程序集

前言今天这篇文章和大家一起学习下C#语言下的命名空间和程序集。在日常的编码工作中&#xff0c;我们对命名空间和程序集都不会很陌生。在创建项目文件时&#xff0c;IDE自动会为我们创建好一个大的命名空间和程序集。大多数业务代码都是在解决方案下各自的命令空间里进行编码的…

C/C++预处理宏的总结

1.定义顺序的无关性 #define PI 3.14 #define TWO_PI 2*PI 这两句谁前谁后无所谓&#xff0c;因为预处理器不断迭代来实现宏替换&#xff0c;直到源文件中没有宏了才停止。 2. 宏变量变成字符串 #define str(x) #x 例子&#xff1a;str (teststring) > "teststrin…

基于jQuery的ajax系列之用FormData实现页面无刷新上传

接着上一篇ajax系列之用jQuery的ajax方法向服务器发出get和post请求写&#xff0c;这篇主要写如何利用ajax和FormData实现页面无刷新的文件上传效果&#xff0c;主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData接口。关于FormData&#xff0c;大家可以看MDN文…

linux网络编程之用多线程实现客户端到服务端的通信(基于udp)

1、开启一个线程接受数据,主线程发送数据的代码 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <netinet/in.h> #include <errno.h> #include <sys/time.h&g…

Apache FTPClient操作文件上传下载及公共类

我们在项目中可能需要使用ftp进行文件的上传、下载、获取服务器目录信息等相关操作&#xff0c;我们可以使用apache的FTPClient进行相关的操作&#xff0c;下面把相关公共方法与大家交流分享&#xff0c;每个方法前都有详细的注释进行讲解&#xff0c;不过在进行ftp测试的时候&…

abd shell关闭所有程序_在后台服务器上运行程序

之前总结过screen的用法&#xff0c;但还可以用nohup命令。nohup工具&#xff1a;Linux系统中有提供一个很好的不挂断地运行命令——nohup。我们使用nohup能很简单的控制使用&#xff0c;在此就简单的介绍一下nohup工具。nohup 命令nohup就是不挂起的意思( no hang up)。用途&a…

优秀的JavaScript模块是怎样炼成的

引言&#xff1a;如今的JavaScript已经是Web上最流行的语言&#xff0c;没有之一。从Github上的语言排行榜https://github.com/languages上即可看出&#xff0c;也是如今最为活跃的开源社区。随着Node的加入&#xff0c;JavaScript开枝散叶进入服务器领域&#xff0c;为这个语言…

解锁JDK 12的奇妙之旅:新特性详解

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解锁JDK 12的奇妙之旅&#xff1a;新特性详解 前言switch表达式拓展NumberFormat对复杂数字的格式化字符串支持transform、indent操作新增方法Files.mismatch(Path, Path)Teeing Collector支持unicode…

.NET6之MiniAPI(十四):跨域CORS(上)

为了说明跨请求&#xff0c;创建了两个项目&#xff0c;一个mini api&#xff0c;端口是5001&#xff0c;另一个razor page项目&#xff0c;端口是5280。5280项目会在页面用ajax的方式来请求5001&#xff0c;形成跨域请求&#xff0c;由于是本地测试&#xff0c;host都是localh…

Linux文件锁学习-flock, lockf, fcntl

参考 linux中fcntl()、lockf、flock的区别 这三个函数的作用都是给文件加锁&#xff0c;那它们有什么区别呢&#xff1f; 首先flock和fcntl是系统调用&#xff0c;而lockf是库函数。lockf实际上是fcntl的封装&#xff0c;所以lockf和fcntl的底层实现是一样的&#xff0c;对文件…