背景
小白菜最近在騰訊云購買了一臺云主機(jī),配置是單核1G,后來我升級到了單核2G,起初系統(tǒng)使用的Windows Server 2012,開機(jī)一看內(nèi)存,我去,500多M沒了,好吧,安裝個(gè)MySql,服務(wù)跑起來,我又去,Mysql吃了400多M,這這這...可憐的配置容不起這個(gè)昂貴的開銷呀,果斷從裝系統(tǒng),這次擁抱了Centos,開機(jī)后舒服多了,90多M,安裝個(gè)Nginx跑restful先。
既然服務(wù)器選擇了Centos,后端的選擇有Nodejs、java、php...等,當(dāng)然還有net-core,于是乎小白菜也嘗嘗鮮,在Centos部署個(gè)net-core版本的restful Api玩玩。
環(huán)境準(zhǔn)備
1. 本地環(huán)境
本地依然使用Windows開發(fā),環(huán)境清單如下
- .NET Core 2.1 SDK
- Visual Studio Code
- 用于Visual Studio Code的C#
下面是下載地址:
https://www.microsoft.com/net/download/archives
https://code.visualstudio.com/download
https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp
安裝完成之后,測試一下是否安裝成功
dotnet --info
2. 服務(wù)器環(huán)境
登錄我們的云主機(jī),如果沒有云主機(jī),也可以在虛擬機(jī)中創(chuàng)建一臺Centos,我使用的是putty進(jìn)行管理。
首先安裝rpm源
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
再安裝.NET SDK
sudo yum update
sudo yum install dotnet-sdk-2.1
測試一下是否安裝成功
dotnet --info
輸出如下信息,可以看到版本號

接著我們在服務(wù)器做一個(gè)Hello World!的控制臺應(yīng)用
dotnet new console -o myApp
cd myApp
dotnet run
輸出了Hello World!

nginx安裝
Nginx (engine x)是C語言開發(fā)的一款輕量級的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器。
1.編譯ngixn依賴gcc環(huán)境,首先安裝編譯環(huán)境
yum install gcc-c++
2.ngxin需要pcre來解析正則表達(dá)式,pcre-devel 是使用pcre開發(fā)的一個(gè)二次開發(fā)庫
yum install -y pcre pcre-devel
3.安裝zlib提供壓縮和解壓縮的方式,nginx使用 zlib對 http 包的內(nèi)容進(jìn)行 gzip
yum install -y zlib zlib-devel
4.安裝OpenSSL,強(qiáng)大的安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及 SSL 協(xié)議,nginx不僅支持 http 協(xié)議,還支持 https(即在ssl協(xié)議上傳輸http),所以需要在 Centos 安裝 OpenSSL庫。
yum install -y openssl openssl-devel
5.下載nginx安裝包
wget -c https://nginx.org/download/nginx-1.10.1.tar.gz
6.解壓并進(jìn)入文件夾
tar -zxvf nginx-1.10.1.tar.gz
cd nginx-1.10.1
7.配置,使用默認(rèn)配置
./configure
8.編譯安裝
make
make install
9.查看ngxin安裝路徑
whereis nginx
10.nginx的相關(guān)命令
#進(jìn)入安裝目錄的sbin文件夾
cd /usr/local/nginx/sbin/
./nginx #啟動(dòng)
./nginx -s stop #停止
./nginx -s quit #退出
./nginx -s reload #重新加載,修改配置文件后
ngxin安裝完畢,啟動(dòng)ngxin后,瀏覽器輸入ip地址,可以看到如下畫面證明安裝成功!

本地編寫api代碼
首先進(jìn)入到你的工作空間,創(chuàng)建空文件夾
mkdir dotnet-core-webapi-test
cd dotnet-core-webapi-test
創(chuàng)建一個(gè)webapi項(xiàng)目,名字就叫TodoApi
dotnet new webapi -o TodoApi
如下圖,創(chuàng)建成功!

然后使用Visual Studio Code打開這個(gè)文件夾,像介樣子

在根目錄添加host.json文件,用于配置api啟動(dòng)的端口,內(nèi)容如下:
{ "url": "http://*:5000" }
修改Program.cs文件,加入配置的url
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var config = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory).AddJsonFile("host.json").Build();
var url = config["url"];
return WebHost.CreateDefaultBuilder(args).UseUrls(url).UseStartup<Startup>();
}
}
按F5運(yùn)行調(diào)試

輸入地址http://localhost:5000/api/values在瀏覽器中查看,輸出了默認(rèn)的值,暫時(shí)不做任何修改,我們本篇的目的是把它部署到生產(chǎn)環(huán)境Centos上。

到目前為止,api項(xiàng)目已經(jīng)跑起來了,我們接下來編譯發(fā)布它。
在vscode中選擇 Terminal > New Terminal打開一個(gè)終端窗口,在底部,默認(rèn)地址是我們的項(xiàng)目文件夾地址。

輸入dotnet publish發(fā)布該項(xiàng)目,發(fā)布到哪里去了,在bin\Debug\netcoreapp2.1\publish下面,就是需要部署到服務(wù)器的內(nèi)所有文件。我們使用psftp將文件上傳到服務(wù)器的/home/wwwroot目錄下,命令如下
#使用密鑰登錄 ppk是密鑰文件
D:\putty\psftp -i D:\putty\opfree.ppk
#輸入賬號和密鑰密碼,這里我使用root用戶登錄
login as: root
Passphrase for key "imported-openssh-key":
#使用put -r “本地目錄” “服務(wù)器目錄”命令,將文件夾上傳到云主機(jī)上
put -r E:\WorkSpace.2018\dotnet-core-webapi-test\TodoApi\bin\Debug\netcoreapp2.1\publish /home/wwwroot
效果如下:

這時(shí)候,文件已經(jīng)上傳至服務(wù)器,我們?nèi)シ?wù)器進(jìn)行部署。
服務(wù)器部署
修改nginx配置文件
#找到nginx的配置文件,在根目錄搜索
cd /
find -name nginx.conf
如下圖:

打開該文件,進(jìn)行修改:
#編輯文件
vi /usr/local/nginx/conf/nginx.conf
#按i鍵進(jìn)入修改模式
#修改完畢按ESC退出,按:進(jìn)入底行模式,輸入wq保存退出
修改內(nèi)容如下,使得80端口的默認(rèn)路徑指向本機(jī)的5000端口

保存成功后,重啟nginx
cd /usr/local/nginx/sbin
./nginx -s quit #退出
./nginx #啟動(dòng)
現(xiàn)在訪問http://45.40.193.247/api/values是會報(bào)錯(cuò)的,因?yàn)?000端口沒有任何東西

啟動(dòng)webapi項(xiàng)目
dotnet /home/wwwroot/TodoApi.dll
此時(shí)再訪問http://45.40.193.247/api/values就得到了api返回值了。

在chorme中查看Headers信息,發(fā)現(xiàn)果然是nginx

進(jìn)程守護(hù)
如果我們此時(shí),將dotnet /home/wwwroot/TodoApi.dll這個(gè)shell關(guān)掉的話,那么對應(yīng)的api服務(wù)也就關(guān)掉了,部署一個(gè)網(wǎng)站,總不能打shell吧,所以我們需要它在后臺進(jìn)行運(yùn)行,并且在服務(wù)器掛機(jī)、重啟之后可以自動(dòng)啟動(dòng)。
ngxin開機(jī)啟動(dòng)
在rc.local增加啟動(dòng)代碼就可以了。
#編輯文件
vi /etc/rc.local
#最底部增加代碼
/usr/local/nginx/sbin/nginx
#設(shè)置執(zhí)行權(quán)限
chmod 755 /etc/rc.local
dotnet項(xiàng)目守護(hù)和開機(jī)啟動(dòng)
supervisor是用Python開發(fā)的一個(gè)client/server服務(wù),是Linux/Unix系統(tǒng)下的一個(gè)進(jìn)程管理工具,我們使用supervisor來守護(hù)我們的todoapi
1.安裝
yum install python-setuptools
easy_install supervisor
2.配置
#在etc下創(chuàng)建目錄supervisor
mkdir /etc/supervisor
#在supervisor下創(chuàng)建目錄conf.d
mkdir /etc/supervisor/conf.d
#拷貝配置文件
echo_supervisord_conf > /etc/supervisor/supervisord.conf
#指定配置文件
supervisord -c /etc/supervisor/supervisord.conf
#打開配置文件編輯
vi /etc/supervisor/supervisord.conf、
#將最后兩行修改為
[include]
files=./conf.d/*.conf
#進(jìn)入目錄 /ect/supervisor/conf.d
cd /ect/supervisor/conf.d
#創(chuàng)建文件 todoapi.conf
vi todoapi.conf
#輸入以下內(nèi)容
[program:todoapi]
command=dotnet TodoApi.dll #要執(zhí)行的命令
directory=/home/wwwroot #命令執(zhí)行的目錄
environment=ASPNETCORE__ENVIRONMENT=Production #環(huán)境變量
user=root #進(jìn)程執(zhí)行的用戶身份
stopsignal=INT
autostart=true #是否自動(dòng)啟動(dòng)
autorestart=true #是否自動(dòng)重啟
startsecs=1 #自動(dòng)重啟間隔
stderr_logfile=/var/log/common.err.log #標(biāo)準(zhǔn)錯(cuò)誤日志
stdout_logfile=/var/log/common.out.log #標(biāo)準(zhǔn)輸出日志
#保存后重新加載配置
supervisorctl shutdown
supervisord -c /etc/supervisor/supervisord.conf
#Supervisor的常用命令
supervisorctl shutdown #關(guān)閉所有任務(wù)
supervisorctl stop|start program_name #啟動(dòng)任務(wù)
supervisorctl status #查看所有任務(wù)狀態(tài)
ps -ef | grep common #查看進(jìn)程信息
退出shell,重啟計(jì)算機(jī),依然可以正常訪問地址“http://45.40.193.247/api/values”。
至此,我們將netcore版本的api已經(jīng)部署到了云主機(jī)上。小伙伴可能會問,為什么不使用5000端口直接訪問呢,因?yàn)樵浦鳈C(jī)為了安全期間,是會屏蔽一些端口的,比如web只開放了80、43,linux ssh登錄的22等少量端口,大多數(shù)時(shí)候,一個(gè)服務(wù)器是不可能只有一個(gè)站點(diǎn)的,所以在最頂層使用nginx進(jìn)行一個(gè)代理,后續(xù)隨著域名的備案完成,ngxin屆時(shí)需要更多的配置,我們會在這臺服務(wù)器使用mysql、nginx域名與二級域名的配置、靜態(tài)資源使用cdn(可能會牽扯到七牛之類的云服務(wù))當(dāng)然必不可少是一個(gè)前端的管理界面(使用vue進(jìn)行構(gòu)建)。
小白菜 - 程序猿
塵埃深處,清醒自持