This site is used to record and share the informations & useful tips during the coding and research.
机器学习项目服务器上线部署全流程记录
Overview1.Java端1.1 安装JDK1.81.2 安装Tomcat71.2.1 配置Tomcat7启动内存1.3 检查安装php和Apache21.4 设置Apache2反向代理1.5 安装MySQL5.71.6 安装配置phpmyadmin2.Perl后台2.1 设置Apache2 CGI2.2 Perl相关模块安装2.3 gearman消息队列安装3. Python相关安装4. R语言及相关包安装 Overview 我们团队完整的机器学习项目已经做了两个了，分别是Bastion4和Bastion6。之前两个项目上线部署的记录过于片段化，针对现在马上要做完的Bastion3项目，我们在此完整记录搭建服务器各种环境的全部流程，以备不时之需。 完整的项目基本分为三大部分：Java处理业务逻辑；Perl后台消息队列；R机器学习模型预测。每个大部分还有很多细节，我们会在每部分都详细记录。 新申请的云服务器预装的仍然是Ubuntu16.04LTS发行版的Linux系统。 1.Java端 Java端负责将用户提交的任务信息提交至后台Perl服务器并记录在MySQL数据库中。因此这部分会安装JDK1.8，Tomcat7和MySQL5.7。 1.1 安装JDK1.8 安装JDK1.8，用apt命令很方便，不用单独下载解压。命令如下： sudo apt-get install software-properties-common -y sudo add-apt-repository ppa:webupd8team/java -y sudo apt-get update sudo apt-get install oracle-java8-installer oracle-java8-set-default -y 安装完成之后，JDK1.8会被安装在/usr/lib/jvm/java-8-oracle中，在/etc/profile或者~/.bashrc中配置JAVA_HOME变量 (我用的是~/.bashrc文件)： export JAVA_HOME=/usr/lib/jvm/java-8-oracle 安装好之后，需要以下命令使配置生效： source ~/.bashrc 1.2 安装Tomcat7 使用以下的命令安装Tomcat7: sudo apt-get install tomcat7 安装过程中，可能会报如下的错误(即使你已经配置好了JAVA_HOME): Jul 09 16:52:16 bastiondb systemd[1]: Starting LSB: Start Tomcat.... Jul 09 16:52:16 bastiondb tomcat7[6413]: * no JDK or JRE found - please...E Jul 09 16:52:16 bastiondb systemd[1]: tomcat7.service: Control process e...1 Jul 09 16:52:16 bastiondb systemd[1]: Failed to start LSB: Start Tomcat.. Jul 09 16:52:16 bastiondb systemd[1]: tomcat7.service: Unit entered fail.... Jul 09 16:52:16 bastiondb systemd[1]: tomcat7.service: Failed with resul.... Hint: Some lines were ellipsized, use -l to show in full. dpkg: error processing package tomcat7 (--configure): subprocess installed post-installation script returned error exit status 1 Errors were encountered while processing: tomcat7 E: Sub-process /usr/bin/dpkg returned an error code (1) 出现这个错误，说明tomcat7已经装好了，但是由于tomcat在启动时找不到JAVA_HOME的路径，所以报错。查看/etc/default/tomcat7，会发现下面这行： #JAVA_HOME=/usr/lib/jvm/openjdk-6-jdk 去掉注释，并改为我们自己的JAVA_HOME路径： JAVA_HOME=/usr/lib/jvm/java-8-oracle 重新运行安装命令： sudo apt-get install tomcat7 安装成功... 安装好之后，tomcat7已经在运行了，使用下面命令查看： ps aux | grep tomcat 用下面的命令启动/停止/重启Tomcat7了: sudo service tomcat7 start/stop/restart 但是现在还有一个问题，Tomcat7的端口是8080，访问的时候必须在地址后面加上:8080，这样看起来不太和谐。由于Apache已经占用了80端口，所以我们采用Apache反向代理转发Tomcat请求的方式来解决这个问题。 1.2.1 配置Tomcat7启动内存 Tomcat启动内存不大，在网站数据量增多的情况下，就会在网页访问时报错，很难根据错误信息推测到这里。我们提前增大Tomcat的启动内存。 修改/usr/share/tomcat7/bin/catalina.sh文件 sudo vim /usr/share/tomcat7/bin/catalina.sh 可以看到： # OS specific support. $var _must_ be set to either true or false. cygwin=false darwin=false os400=false case "`uname`" in CYGWIN*) cygwin=true;; Darwin*) darwin=true;; OS400*) os400=true;; 在这段前面添加： JAVA_OPTS="-Xmx4096m" 就可以将tomcat启动内存增加为4G，保存并重启tomcat，就可以了。 下面的内容选择性安装，如果没有特殊需求，最好不要修改 默认的tomcat工作主目录为/var/lib/tomcat6/，网站目录为/var/lib/tomcat6/webapps，如果你的文章会产生大量文件，并且需要存放在网站的目录下，那这个目录就不太合适，因为这个目录通常占用的是系统盘空间。 假设你有一个新的扩展盘，目录为/my_extended_disk，在上面创建一个目录为tomcatWebapps，并想把这个目录，当做你的tomcat网站目录，修改/etc/tomcat7/server.xml sudo vim /etc/tomcat7/server.xml 把 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> 修改为 <Host name="localhost" appBase="/my_extended_disk/tomcatWebapps" unpackWARs="true" autoDeploy="true"> 然后重启服务器，就可以了。 1.3 检查安装php和Apache2 一般来说，装好的Ubuntu 16.04系统都会默认装好php和Apache2，但配置使用之前最好还是检查一下。 使用下面命令检查php： php -v 如果已经安装，大概会显示下面的内容： PHP 7.0.32-0ubuntu0.16.04.1 (cli) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.0.32-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies 说明安装了php 7.0。如果没装的话，用下面的命令安装： sudo apt-get install php7.0 在Ubuntu 16.04中，直接用 sudo apt-get install php 默认安装的也是php7.0版本。 使用下面命令检查Apache2： apache2 -v 如果已经安装，大概会显示下面的内容： Server version: Apache/2.4.18 (Ubuntu) Server built: 2018-04-18T14:53:04 说明没装的话，用下面的命令安装： sudo apt-get install apache2 注意：如果php和Apache2都没有安装的情况下，安装顺序一定要先装php，在装Apache2，如果顺序反了，可能会导致Apache2服务器不能识别php页面，在你访问这些页面的时候，直接显示页面的代码，而不是页面本身。 参见 php页面不能被解析成网页，而是直接显示了页面代码。 1.4 设置Apache2反向代理 Apache2默认是随系统安装的，但有时候为了快速安装，去掉了也有可能。由于Apache2是随系统自动启动的，如果Apache2已经安装了并且没有人主动关闭的话，使用： ps aux | grep apache2 就应该看到进程信息，如果没看到，用下面的命令安装： sudo apt-get install apache2 安装成功之后，使用服务器的地址(比如bastion3.erc.monash.edu)访问，就应该看到Apache2的欢迎界面。 如果安装成功，但是网址却无法访问，说明80端口没开，联系管理员，打开这个端口。 修改Apache2配置文件： sudo vim /etc/apache2/apache2.conf 在文件末尾添加以下内容： ProxyPass / http://bastion3.erc.monash.edu:8080/ ProxyPassReverse / http://bastion3.erc.monash.edu:8080/ 可以让Apache2把http://bastion3.erc.monash.edu请求转发到http://bastion3.erc.monash.edu:8080/由tomcat7处理。如果你在Apache2中有一个网站cgi-bin，你访问http://bastion3.erc.monash.edu/cgi-bin时，就想访问Apache2下的cgi-bin，而不是转成http://bastion3.erc.monash.edu:8080/cgi-bin由tomcat7处理，那么改成这样就可以了： ProxyPass /phpmyadmin ! ProxyPass /cgi-bin ! ProxyPass / http://bastion3.erc.monash.edu:8080/ ProxyPassReverse / http://bastion3.erc.monash.edu:8080/ 注意：这里同时写了一个phpmyadmin的配置，是因为我们会使用phpmyadmin管理和访问数据库。参考1.6小节的内容。 重启Apache2服务： sudo service apache2 restart 如果报错： Job for apache2.service failed because the control process exited with error code. See "systemctl status apache2.service" and "journalctl -xe" for details. 根据提示，使用 systemctl status apache2.service 查看错误信息： Jul 09 17:15:56 bastiondb apache2[7914]: * The apache2 configtest failed. Jul 09 17:15:56 bastiondb apache2[7914]: Output of config test was: Jul 09 17:15:56 bastiondb apache2[7914]: AH00526: Syntax error on line 223 o Jul 09 17:15:56 bastiondb apache2[7914]: Invalid command 'ProxyPass', perhap Jul 09 17:15:56 bastiondb apache2[7914]: Action 'configtest' failed. Jul 09 17:15:56 bastiondb apache2[7914]: The Apache error log may have more Jul 09 17:15:56 bastiondb systemd[1]: apache2.service: Control process exite Jul 09 17:15:56 bastiondb systemd[1]: Failed to start LSB: Apache2 web serve Jul 09 17:15:56 bastiondb systemd[1]: apache2.service: Unit entered failed s Jul 09 17:15:56 bastiondb systemd[1]: apache2.service: Failed with result 'e 发现Apache2不能识别新添加的ProxyPass，导致重启失败。这是因为Apache2的代理模块proxy_http未启用，使用下面命令： sudo a2enmod proxy_http 重新启动Apache2： sudo service apache2 restart 成功...这时候再输入服务器的地址，即可访问到tomcat的默认项目了，后面不用加:8080。 1.5 安装MySQL5.7 先更新一下系统，再用apt-get命令直接安装： sudo apt-get update sudo apt-get install mysql-server 安装过程会让选择yes/no,选yes；还有就是设置root用户密码。 安装完成可以查看是不是安装好了,即查看MySQL的状态： sudo service mysql status 显示如下即可： ?.mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2018-03-19 14:35:03 UTC; 27s ago Main PID: 17432 (mysqld) CGroup: /system.slice/mysql.service ?..17432 /usr/sbin/mysqld Mar 19 14:35:02 bastion3 systemd[1]: Starting MySQL Community Server... Mar 19 14:35:03 bastion3 systemd[1]: Started MySQL Community Server. 安装好之后，可以用以下命令启动/停止/重启： sudo service mysql stop/stop/restart 本项目的数据的形式和之前项目的很相似，所以可以将之前的Bastion6项目数据库文件导出，然后再导入本项目。 导出命令： mysqldump -uroot -p bastion6 > bastion6.sql 回车之后输入数据库密码即可。 将bastion6.sql内容修改为自己需要的： CREATE DATABASE IF NOT EXISTS bastion3; USE bastion3; DROP TABLE IF EXISTS `job`; CREATE TABLE `job` ( `jobID` int(100) NOT NULL AUTO_INCREMENT, `jobName` varchar(256) NOT NULL, `orgnization` varchar(1000) , `email` varchar(100) NOT NULL, `status`int(1) NOT NULL, `createTime` datetime NOT NULL, `startTime` datetime , `endTime` datetime , `sequence` longtext NOT NULL, `sequenceNumber` int(10) NOT NULL, PRIMARY KEY (`jobID`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `predictresult`; CREATE TABLE `predictresult` ( `jobID` int(100) NOT NULL AUTO_INCREMENT, `jobName` varchar(256) NOT NULL, `predictionResult` longtext, PRIMARY KEY (`jobID`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pssm`; CREATE TABLE `pssm` ( `id` int(100) NOT NULL AUTO_INCREMENT, `seq` varchar(10000), `output` varchar(500) , PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `downloadInfo`; CREATE TABLE `downloadInfo` ( `id` int(100) NOT NULL AUTO_INCREMENT, `type` varchar(10000), `count` varchar(500) , PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8; INSERT INTO `downloadInfo` VALUES (1,'originalData','0'),(2,'independentData','0'),(3,'predictData','0'); 然后登录数据库: mysql -u root -p 回车之后输入密码。 将上面的SQL命令输入，回车即可创建完整的数据库表。 至此，Java部分安装配置就算完成了。 1.6 安装配置phpmyadmin 命令行查看和管理MySQL还是有点不方便，所以我们这里安装一个phpmyadmin，就可以使用web界面查看和操作数据库。 这时候直接使用网址+phpmyadmin，浏览器会显示找不到phpmyadmin。那是因为apache2默认的网站路径是/var/www/html，而不是/var/www，编辑/etc/apache2/sites-enabled/000-default.conf： sudo vim /etc/apache2/sites-enabled/000-default.conf 把DocumentRoot /var/www/html修改为DocumentRoot /var/www 重启apache2，重新访问，就可以了。 安装phpmyadmin sudo apt-get install phpmyadmin 安装过程中，会弹出一个Configuring phpmyadmin框，让你选择要运行phpmyadmin的服务器，默认是apache2，还可以选择lighttpd，因为我们之前安装的web服务器是apache2，所以直接敲回车就行了。 然后安装一阵子继续弹出一个Configuring phpmyadmin框，提示你是否需要配置数据库，毕竟phpmyadmin本身就是管理数据库的，不配置好数据库，也就没有安装的意义了，默认选择的是Yes，回车，会转到新的界面让你输入密码，也就是刚才安装MySQL时设置的密码，输入之后敲回车确认，再重复确认密码，完成安装。 安装完成之后，发现在apache2的网站目录/var/www下，并没有多出来一个phpmyadmin，这是因为Ubuntu系统在安装phpmyadmin时，默认安装在了/usr/share/下: ls /usr/share/ 就可以看到里面有phpmyadmin。 我们直接创建一个软连接： sudo ln -s /usr/share/phpmyadmin /var/www/phpmyadmin 这样就可以在/var/www下访问到phpmyadmin。 如果发现虽然能访问phpmyadmin了，但是浏览器直接显示了代码，而不是网页，说明apache2没有自动安装解析php的包。 先用下面的命令看看你装的php版本： php --version 如果是php7.0，那么安装下面的包： sudo apt-get install libapache2-mod-php7.0 然后重启apache2，现在应该可以访问到正常的网页了。具体原因，参见php页面不能被解析成网页，而是直接显示了页面代码。 用户名是root，密码是MySQL设置的密码。 注意： 由于phpmyadmin网站暴露在公网之后，可能会招到攻击，比如使用脚本破解密码等，因此我们需要配置一下白名单，中只允许指定IP访问。修改/etc/apache2/apache2.conf，在里面添加: Options Indexes FollowSymLinks Includes ExecCGI AllowOverride All # Key configuration for white list Order Deny,Allow Allow from xx.xx.xx.xx Allow from xx.xx.xx.xy Deny from All 其中，/var/www/phpmyadmin为phpmyadmin网站路径，xx.xx.xx.xx和xx.xx.xx.xy为允许访问的IP地址。 2.Perl后台 Perl的主要作用是它的消息队列以及和Java通讯的CGI模块。因此需要配置Apache2 CGI以及安装相应的Perl模块。 2.1 设置Apache2 CGI 在安装CGI模块之前，最好先将make安装好： sudo apt-get install make 然后安装Perl的CGI模块，推荐使用cpan命令安装 (一定要用sudo权限打开)： 先打开cpan： sudo cpan 然后输入下面的命令: install CGI 下面修改CGI程序的根目录： sudo vim /etc/apache2/apache2.conf 将配置文件中对应的地方改为如下： Options Indexes FollowSymLinks AllowOverride None Require all granted 在/var/www/cgi-bin目录中新建一个cgi_test.pl文件，以创建一个Perl CGI网站，文件内容为： #!/usr/bin/perl -w use warnings; use CGI qw(:standard); #! must use 'my' to define a variable print header; my $now_string = localtime(); print "Hello, CGI using Perl! It's $now_string NOW! "; 为此文件添加执行权限： sudo chmod +x /var/www/cgi-bin/cgi_test.pl 在命令行中执行此文件： sudo perl /var/www/cgi-bin/cgi_test.pl 如果之前的设置正确，则会显示以下内容： Content-Type: text/html; charset=ISO-8859-1 Hello, CGI using Perl! It's Tue Mar 20 14:17:15 2018 NOW! 至此，虽然可以在命令行中运行此程序，但是还不能作为服务器远程访问。我们需要做以下配置，让Apache2对Perl支持： sudo vim /etc/apache2/sites-enabled/000-default.conf 将下面的内容： ... ServerAdmin webmaster@localhost DocumentRoot /var/www ... ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined 修改为： ... ServerAdmin webmaster@localhost DocumentRoot /var/www ScriptAlias /cgi-bin/ /var/www/cgi-bin/ AllowOverride all Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all AddHandler cgi-script .cgi .pl ... ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined 在Apache中启用CGI模块。注意 VirtualHost *:80这里的端口号尽量不要改动，因为使用网址或者ip地址访问，不加端口号的话，默认就是访问80端口号，如果改了端口号，就得显示加上。 默认情况下，这个模块是没有开启的，这点可以用以下命令确认： ls -l /etc/apache2/mods-enabled/ | grep cgi 显示为空表示当前启用的与CGI相关的模块为空。用下面的命令查看有哪些模块可以被启用： ls -l /etc/apache2/mods-available/ | grep cgi 显示如下： -rw-r--r-- 1 root root 74 Mar 19 2016 authnz_fcgi.load -rw-r--r-- 1 root root 115 Mar 19 2016 cgid.conf -rw-r--r-- 1 root root 60 Mar 19 2016 cgid.load -rw-r--r-- 1 root root 58 Mar 19 2016 cgi.load -rw-r--r-- 1 root root 89 Mar 19 2016 proxy_fcgi.load -rw-r--r-- 1 root root 89 Mar 19 2016 proxy_scgi.load 这样，我们在mods-enabled中创建软连接，指向mods-available中的cgid.*文件： sudo ln -s /etc/apache2/mods-available/cgid.load /etc/apache2/mods-enabled/ sudo ln -s /etc/apache2/mods-available/cgid.conf /etc/apache2/mods-enabled/ 重启Apache服务器： sudo service apache2 restart 此时，如果在浏览器中访问：http://bastion3.erc.monash.edu/cgi-bin/cgi_test.pl应该会显示： Hello, CGI using Perl! It's Tue Mar 20 14:17:15 2018 NOW! 这样就算成功了。 2.2 Perl相关模块安装 在安装这部分模块之前，最好保证gcc和g++两个程序已经安装好了，如果没有安装好，那么按照以下命令安装： sudo apt-get install gcc sudo apt-get install g++ Perl模块仍然要使用sudo cpan命令安装，然后依次输入以下命令： install Storable install DBI install IO::All install Bio::SeqIO install Bio::Seq install Capture::Tiny install SOAP::Transport::HTTP install MIME::Lite install Mail::Sendmail 2.3 gearman消息队列安装 当前最新版的gearman是gearmand-1.1.12。我们执行下面几步，先将其下载到本地主文件夹，并解压缩。 cd ~ sudo apt-get update wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz tar zxvf gearmand-1.1.12.tar.gz cd gearmand-1.1.12/ 进入gearmand-1.1.12文件夹后，如果直接运行 ./configure 就会报缺少如下几个依赖包错误： configure: error: could not find boost configure: error: Could not find a version of the library configure: error: could not find gperf configure: error: Unable to find libevent configure: error: Unable to find libuuid 所以，我们先将这些依赖都安装好： sudo apt-get install libboost-dev sudo apt-get install libboost-all-dev sudo apt-get install gperf sudo apt-get install libevent-dev sudo apt-get install uuid-dev 安装好之后，如果没有错误，则运行： ./configure 然后仍在gearmand-1.1.12文件夹下运行下面两条命令，编译时间比较长： sudo make sudo make install 这个过程中如果出现了错误，就运行下面的命令清除一下之前编译产生的可执行文件以及object文件(即扩展名为o的文件)： sudo make clean 继续重新安装编译： ./configure sudo make sudo make install 没有错误的话，就安装gearman的job server： sudo apt-get install gearman-job-server 安装好以后，运行一下gearman: gearman -d 会提示错误： gearman: error while loading shared libraries: libgearman.so.8: cannot open shared object file: No such file or directory 这表示找不到libgearman.so.8所在的目录。这时我们打开/etc/ld.so.conf文件： sudo vim /etc/ld.so.conf 添加一句话: include /usr/local/lib 保存退出，并执行下面这句： sudo /sbin/ldconfig 这样就不会出错了。 启动一下job server： gearmand -d 报错如下： gearmand: Could not open log file "/usr/local/var/log/gearmand.log", from "/home/ubuntu/gearmand-1.1.12", switching to stderr. (No such file or directory) 我们这样解决：在/usr/local/下面新建var子目录，进去，新建log子目录，再进去，新建文件gearmand.log。这样就没有问题了。 用sudo权限运行下面的命令： sudo gearmand -d -L 127.0.0.1 -p 4730 -d表示daemon，在后台运行； -L表示监听的ip，默认是localhost； -p表示监听的端口号port，默认是4730。 此时，使用下面的命令，即可查看gearman当前状态： sudo lsof -i:4730 如果显示如下，就表示成功安装： COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 27831 gearman 10u IPv4 320614 0t0 TCP localhost:4730 (LISTEN) 这样gearman在ubuntu16.04上面就安装成功了。 至此，我们还需要安装三个Perl模块： Gearman::Server Gearman::Client Gearman::Worker 在安装Gearman::Server的时候，需要依赖Net::SSLeay,IO::Socket::SSL和Gearman::Util,而安装Net::SSLeay的时候，如果没有libssl-dev这个系统包，是安装不上Net::SSLeay的。所以我们必须要先安装好libssl-dev。 sudo apt-get install libssl-dev 然后必须按顺序依次安装Net::SSLeay，顺序不能乱: 继续打开cpan： sudo cpan 然后 install Net::SSLeay install IO::Socket::SSL install Gearman::Util 依次安装： install Gearman::Server install Gearman::Client install Gearman::Worker 都安装后之后，可以重启一下机器。 启动之后，用如下命令观察4730端口，查看gearman的job server是否已经启动(gearmand -d这条命令是否生效)： sudo lsof -i:4730 显示如下： COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gearmand 907 gearman 10u IPv4 21414 0t0 TCP localhost:4730 (LISTEN) 可以知道，这个server是开机自启动的。 至此，gearman消息队列的安装就算完成了。 每次重启服务器，都需要重启worker脚本。worker和client脚本都会放在/var/www/cgi-bin/目录下面，因此启动worker和命令如下(比如我们要开16个worker)： sudo nohup perl /var/www/cgi-bin/worker_bastion3.pl >~/worker_bastion3_log_1.txt & sudo nohup perl /var/www/cgi-bin/worker_bastion3.pl >~/worker_bastion3_log_2.txt & sudo nohup perl /var/www/cgi-bin/worker_bastion3.pl >~/worker_bastion3_log_3.txt & sudo nohup perl /var/www/cgi-bin/worker_bastion3.pl >~/worker_bastion3_log_4.txt & ... sudo nohup perl /var/www/cgi-bin/worker_bastion3.pl >~/worker_bastion3_log_16.txt & 而client会在提交任务的时候，由Java调用，因此不需要我们手动启动。 现在不再需要手动重启了。 运行sudo crontab -e（e代表edit），可以编辑创建一个cron任务，可能需要先选择编辑器，熟悉哪个选哪个就行了，我选的3. vim： @reboot cd /var/www/cgi-bin && sudo perl /var/www/cgi-bin/worker_Bastion3.pl > /var/log/worker_Bastion3_log_1.txt 2>&1 @reboot cd /var/www/cgi-bin && sudo perl /var/www/cgi-bin/worker_Bastion3.pl > /var/log/worker_Bastion3_log_2.txt 2>&1 @reboot cd /var/www/cgi-bin && sudo perl /var/www/cgi-bin/worker_Bastion3.pl > /var/log/worker_Bastion3_log_3.txt 2>&1 @reboot cd /var/www/cgi-bin && sudo perl /var/www/cgi-bin/worker_Bastion3.pl > /var/log/worker_Bastion3_log_4.txt 2>&1 ... @reboot cd /var/www/cgi-bin && sudo perl /var/www/cgi-bin/worker_Bastion3.pl > /var/log/worker_Bastion3_log_16.txt 2>&1 这样之后服务器重启，就不必再手动开这些进程了。 使用sudo crontab -l(l代表list)可以查看所有你创建的cron任务。注意：用sudo创建的任务用sudo查看，才能看得到，同样sudo crontab -l查看不到crontab -e 创建的任务。 相对于手动执行脚本，这里的配置有三个变化： 把log日志重定向到了/var/log/目录下，可以直接在这里查看错误信息。 不再需要用nohup命令了，nohup是因为我们用ssh登录，需要在ssh退出后脚本依然运行才这么做的，现在重启时系统系统这个脚本，这个脚本会一直留在系统中，不必再用nohup。 由cron启动脚本时，当前工作目录可能跟想象中不一样，我们执行sudo perl /var/www/cgi-bin/worker_bastion3.pl（不管用不用nohup）时，脚本的工作目录在/var/www/cgi-bin，而由cron执行时，当前工作目录却是sudo perl /var/www/cgi-bin/worker_bastion3.pl，导致脚本中使用相对目录的地方会报错，比如这里： $seqs > io("sequence/$jobName.fasta"); … 当然，好的习惯是尽量不要用相对路径，因为你不知道这个脚本会在哪里或者哪种环境下执行，执行时的当前工作目录也可能无法预测。 3. Python相关安装 Python在此系列项目当中，主要是用来提取特征，因此需要依次安装以下几个工具包： sudo apt-get install python-scipy sudo apt-get install python-dev sudo apt-get install python-numpy sudo apt-get install python-matplotlib sudo apt-get install python-pandas sudo apt-get install python-sklearn 4. R语言及相关包安装 R语言在此系列项目当中，既要提取部分特征，又要负责训练模型，还要使用ggplot2画图，所以有很多相关的包是要安装的。 首先安装R语言： sudo apt-get install r-base 然后安装以下几个包 (其实这个服务器在机器学习部分主要作用就是预测，因为训练部分的工作都会在线下进行，不过仍然将所有机器学习部分必须的包都记录在此，以备查阅)。 sudo权限启动R语言： sudo R 这里必须用sudo启动R安装，这样R包一般会安装在/usr/local/lib/R/site-library中，不用sudo权限，会把R包装在当前用户的个人空间，比如~/R/x86_64-pc-linux-gnu-library/3.2。在普通状态下这两个位置并无不同，但是如果当前用户进入root模式(比如用sudo -i命令)，再使用R就不能正确找到R包了。很不幸，因为我们用了crontab设置了worker开机自启动，导致在sudo模式调用了worker的程序，并由worker进一步调用了R程序，就没能找到普通权限下安装的R包，导致报错了。 然后在启动的R语言对话框中输入以下命令： install.packages("protr") install.packages("caret") install.packages("e1071") install.packages("plyr") install.packages("RSNNS") install.packages("ROCR") install.packages("ggplot2") install.packages("randomForest") 至此一个完整的机器学习项目的服务器就已经算是搭建好了。 需要格外注意的是，因为我们的缓存文件都在外接硬盘上，所以每次都重启服务器之后都需要手动加载此硬盘： sudo mount /dev/vdb /bastion3_cache/ 现在不用这么做了，通过配置/etc/fstab可以直接再重启服务器时自动挂载，在/etc/fstab文件中添加下面的行（需要用sudo编辑）： /dev/vdb /bastion3_cache auto defaults,nofail,x-systemd.requires=cloud-init.service,comment=cloudconfig 0 2 其中，/dev/vdb是要挂在的物理硬盘盘符，/bastion3_cache是挂载盘目录。 如果你不清楚哪个盘需要挂载，用df -h查看： ubuntu@bastion3:~$ df -h Filesystem Size Used Avail Use% Mounted on udev 32G 0 32G 0% /dev tmpfs 6.3G 180M 6.2G 3% /run /dev/vda1 9.9G 4.2G 5.2G 45% / tmpfs 32G 0 32G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 32G 0 32G 0% /sys/fs/cgroup /dev/vdb 473G 9.0G 440G 3% /bastion3_cache tmpfs 6.3G 0 6.3G 0% /run/user/1000 如果有硬盘为未挂载，那Mounted on这列应该是空的，或者是/mnt（默认挂载在/mnt目录）。挂载前需要自己创建一个目录，比如sudo mkdir /bastion3_cache。