华南农业大学 Linux 综合实验速通指南

本指南将帮助你在无需配置 Nginx 和 Apache 等服务端的情况下速通 Linux 综合实验 90 +。

系统版本:Ubuntu 20.04

如果你使用的是 CentOS,在安装软件的环节请使用 yum,其它不变。

建议以 root 用户操作

安全组端口列表

请在服务器的安全组或防火墙中开放以下端口:

  • 8080 用于演示 Go 版本
  • 8081 用于演示 PHP 版本
  • 8082 用于演示 Python 版本
  • 8083 用于演示 Nodejs 版本

当然如果使用 Nginx 等服务端通过正则匹配 uri 进行内网代理转发,便无需向公网开放这些端口,但本指南力求简单为主,便不介绍这种方式。

如果你需要在本地使用 Navicat 等图形化数据库管理工具,还需额外开放 3306 端口。在 Navicat 连接时主机填写服务器的公网 IP 即可。

MySQL 安装与配置

安装 MySQL

1
apt-get install mysql-server

启动 MySQL

1
service mysql start

进入 MySQL 控制台

1
mysql -uroot

创建数据库

1
2
create databse linux;
use linux;

创建数据表

1
2
3
4
5
6
7
8
9
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
`student_number` bigint NULL DEFAULT NULL,
`user_id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`user_id`) USING BTREE
) AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
# 添加姓名、学号、id
INSERT INTO `users` VALUES ("姓名", 12345, 1);

添加 linux 用户并赋予权限

1
2
3
4
create user "linux"@"%";
ALTER USER 'linux'@'%' IDENTIFIED BY 'linux';
grant select,insert,update on linux.* to "linux"@"%";
flush privileges;

添加 nodejs 用户并赋予权限(此处是因为 nodejs 不支持新版 MySQL 加密方式,所以需要单独为它开一个用户,也可以只开这一种用户,但是本指南在实践时采用的是新开一个用户的方式)

1
2
3
4
create user "nodejs"@"%";
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
grant select,insert,update on linux.* to "nodejs"@"%";
flush privileges;

输入 exit 可以退出

验证创建的用户是否生效

1
mysql -ulinux -p

随后输入密码(无回显)回车,若登录成功即为创建成功

Supervisor 安装

Supervisor 是一款强大的进程管理工具,可以帮助我们维护应用程序的进程,并在其意外终止时重启。

1
apt-get install supervisor

新建 Supervisor 配置文件

1
touch /etc/supervisor/conf.d/linux.conf

Go

获取 Go 安装包并解压

1
wget -c https://golang.google.cn/dl/go1.18.2.linux-amd64.tar.gz | tar -xz -C /usr/local

添加环境变量,即在 /etc/profile 中添加行

1
export PATH=$PATH:/usr/local/go/bin

使环境变量生效

1
source /etc/profile

测试 Go 版本

1
go version

至此 Go 安装完成。下面开始编写 Go 程序。

新建 Go 文件夹

1
mkdir -p /var/www/linux_exp/go

cd 进入该文件夹,在该文件夹下新建两个文件

go.mod

1
2
3
4
5
6
7
8
module GoLinux

go 1.18

require (
github.com/go-sql-driver/mysql v1.6.0
github.com/jmoiron/sqlx v1.3.5
)

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import (
"encoding/json"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"log"
"net/http"
)

var database *sqlx.DB

type User struct {
StudentNumber int `db:"student_number" json:"student_number"`
Name string `db:"name" json:"name"`
UserId int `db:"user_id" json:"user_id"`
}

func Say(w http.ResponseWriter, r *http.Request) {
var users []User
sql := "select * from users where user_id=1 "
err := database.Select(&users, sql)
if err != nil {
fmt.Println("exec failed, ", err)
return
}
res, _ := json.Marshal(users)
_, err = w.Write(res)
if err != nil {
log.Fatalln(err)
}
}

func main() {
var err error
database, err = sqlx.Open("mysql", "linux:linux@tcp(127.0.0.1:3306)/linux")
if err != nil {
log.Fatalln(err)
return
}
http.HandleFunc("/", Say)
err = http.ListenAndServe("0.0.0.0:8080", nil)
if err != nil {
log.Fatalln(err)
return
}
}

配置 Go 库镜像

1
2
go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

下载 Go 运行库

1
go mod tidy

编译 Go 程序

1
go build main.go

给予 main 执行权限

1
chmod +x main 

尝试运行

1
./main

通过主机访问 公网IP:8080,查看是否有信息打印出现,若有即为成功。使用 Ctrl+C 终止程序。

编辑刚刚新建的 Supervisor 配置文件

1
vim /etc/supervisor/conf.d/linux.conf

添加以下内容

1
2
3
4
5
6
[program:linux_go]
command=/var/www/linux_exp/go/main
autostart=true
autorestart=true
stderr_logfile=/tmp/linux_go.log
stdout_logfile=/tmp/linux_go.log

执行指令

1
supervisorctl update

再次访问 公网IP:8080,若出现信息即为成功。

PHP

从这里开始将精简介绍

1
apt-get install php

/var/www/linux_exp 下新建 php 文件夹,在里面新建 main.php,写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
$servername = "localhost";
$username = "linux";
$password = "linux";
$dbname = "linux";

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname, 3306);
// Check connection
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}

$sql = "SELECT * FROM users";
$result = $conn->query($sql);

$res = [];
if ($result->num_rows > 0) {
// 输出数据
while($row = $result->fetch_assoc()) {
$row['student_number'] = (int)$row['student_number'];
$row['user_id'] = (int)$row['user_id'];
$res[] = $row;
}
}
header('Content-Type: application/json');
echo json_encode($res);
$conn->close();
?>

在 supervisor 配置文件中写入

1
2
3
4
5
6
7
[program:linux_php]
command=php -S 0.0.0.0:8081 main.php
autostart=true
autorestart=true
stderr_logfile=/tmp/linux_php.log
stdout_logfile=/tmp/linux_php.log
directory=/var/www/linux_exp/php

更新配置

1
supervisorctl update

访问 公网IP:8081 即可

Python

此处必须使用 Python3,安装 Python3

1
apt-get install python3 pip

安装 pymysql 库

1
pip install pymysql

/var/www/linux_exp 下新建 python 文件夹,在里面新建 main.py,写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import pymysql


class Request(BaseHTTPRequestHandler):
def do_GET(self):
db = pymysql.connect(
host='localhost',
user='linux',
password='linux',
database='linux',
charset='utf8'
)
c = db.cursor()
c.execute("select * from users")
res = []
for i in range(c.rowcount):
record = c.fetchone()
res.append({'name': record[0], 'student_number': record[1], 'user_id': record[2]})
db.close()
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(res).encode())


if __name__ == '__main__':
server = HTTPServer(('0.0.0.0', 8082), Request)
server.serve_forever()

在 supervisor 配置文件中写入

1
2
3
4
5
6
7
[program:linux_python]
command=python3 main.py
autostart=true
autorestart=true
stderr_logfile=/tmp/linux_python.log
stdout_logfile=/tmp/linux_python.log
directory=/var/www/linux_exp/python

更新配置

1
supervisorctl update

访问 公网IP:8082 即可

Nodejs

1
apt install nodejs npm

/var/www/linux_exp 下新建 nodejs 文件夹,在里面新建 main.js,写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const http = require('http');

const port = 8083;
const hostname = "0.0.0.0"

var mysql = require('mysql');

const server = http.createServer((req, res) => {
var connection = mysql.createConnection({
host : 'localhost',
user : 'nodejs',
password : 'nodejs',
port: 3306,
database: 'linux'
});

connection.connect();

res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');

var sql = 'SELECT * FROM users';
connection.query(sql,function (err, result) {
if(err){
console.log('[SELECT ERROR] - ',err.message);
return;
}
res.end(JSON.stringify(result));
});
connection.end()
})

server.listen(port, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`);
});

在同一目录下安装 nodejs 的 mysql 库

1
npm install mysql

在 supervisor 配置文件中写入

1
2
3
4
5
6
7
[program:linux_nodejs]
command=node main.js
autostart=true
autorestart=true
stderr_logfile=/tmp/linux_nodejs.log
stdout_logfile=/tmp/linux_nodejs.log
directory=/var/www/linux_exp/nodejs

更新配置

1
supervisorctl update

访问 公网IP:8083 即可