ASP.NET跨平台最佳實踐


前言

八年的堅持敵不過領導的固執,最終還是不得不闊別已經成為我第二語言的C#,轉戰Java陣營。有過短暫的失落和迷茫,但技術轉型真的沒有想象中那么難。回頭審視,其實單從語言本身來看,C#確實比Java更優秀(並非C#天生麗質,而是它站在了巨人的肩膀上)。

本文並非為.NET正名而來,而僅僅是分享作者近幾年在ASP.NET跨平台方面的研究與實踐經驗,算是對八年的.NET之路作一個階段性的總結。

.NET技術自誕生以來,便一直因其跨平台能力差而廣受詬病。這里面有微軟有意為之,也有別有用心之人在混淆視聽。.NET在一開始便是按公開的語言規范進行設計,隨着微軟的逐漸妥協,.NET Framework已完全開源。.NET跨平台技術迎來了前所未有的機會,各種.NET跨平台技術必將如雨后春筍般涌現。本文將介紹作者在.NET跨平台方面的最佳實踐經驗,希望藉以降低.NET跨平台的技術難度,讓.NET真正成為跨平台的生產技術。

環境

操作系統選擇開源社區較有代表性的Linux服務器版本CentOS(本文所述的跨平台思路可以成功應用於絕大多數的Linux系統,也包括國產操作系統如中標麒麟);技術平台選擇久負盛名的Mono;Web應用中間件選擇中國制造的Jexus。涉及的環境與技術詳細情況為:

  • 操作系統:CentOS_6.4_64bit
  • .NET框架:Mono_4.0.4.1
  • Web應用中間件:Jexus_5.6.5
  • 數據庫:MySQL_5.1.73

目標

本文所述實踐,將實現ASP.NET應用程序在Linux系統進行部署,並作產品化嘗試,使ASP.NET應用在Linux平台易於部署和維護。

Web應用程序

本文的Web應用程序選用ASP.NET MVC 4技術開發,持久層選用ADO.NET Entity Framework 6技術。你可以在src/demo目錄下找到它。

跨平台部署

一、安裝系統

最小化安裝CentOS系統。作為實驗環境,可以考慮選用具有快照功能的虛擬機,作者選用的VMWare虛擬機進行試驗。系統安裝在此不再贅述。系統安裝好后,做一個快照留待后續驗證產品化安裝包正確性所用。

如果你對跨平台部署ASP.NET應用的實現過程沒有興趣,只想看結果的話,可以直接跳過后續步驟,直接進入產品化章節的通過安裝包部署ASP.NET應用部分。

二、搭建Linux編譯環境

由於本文選擇源碼安裝Mono,所以需要先搭建Linux編譯環境。搭建Linux編譯環境需要讓系統連接互聯網,並進行系統更新。

首先,需要讓你的系統連接互聯網。此處以VMWare虛擬機為例講解如何連接互聯網。VMWare虛擬機連接互聯網的方式很多,作者選擇NAT方式,首先需要將虛擬機網絡連接方式設為NAT,如圖 1所示。

                       

1 VMWare虛擬機網絡連接方式設置

設置VMnet8為自動獲取IP,如圖 2所示。

 

2 設置VMnet8為自動獲取IP地址

然后將Linux虛擬機設為DHCP自動分配IP,編輯網卡配置文件:

[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0

修改該配置文件內容如下:

DEVICE=eth0
HWADDR=00:0C:29:F5:09:30
TYPE=Ethernet
UUID=74b949f0-57bb-4baa-a5f2-2c97fb533a8b
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp

重啟網絡服務,讓網卡設置生效:

[root@localhost ~]# service network restart

確認虛擬機已連接互聯網:

[root@localhost ~]# ping yilin.cnblogs.com
PING yilin.cnblogs.com (42.121.252.58) 56(84) bytes of data.
64 bytes from 42.121.252.58: icmp_seq=1 ttl=128 time=77.7 ms
64 bytes from 42.121.252.58: icmp_seq=2 ttl=128 time=78.1 ms
64 bytes from 42.121.252.58: icmp_seq=3 ttl=128 time=77.5 ms

更新系統:

[root@localhost ~]# yum –y update

安裝Mono源碼安裝需要的組件:

[root@localhost ~]# yum -y install wget glib2-devel libtiff libtiff-devel libjpeg libjpeg-devel giflib giflib-devel libpng libpng-devel libX11 libX11-devel freetype freetype-devel fontconfig fontconfig-devel libexif libexif-devel gcc-c++ gettext unzip zip

三、安裝GDI+組件

安裝Mono之前,需要先安裝其依賴的GDI+組件。聯網下載libgdiplus源碼安裝包(如果在Linux系統中直接下載源碼包出現停滯的情況,請返回Windows系統下載libgdiplus源碼安裝包,並將其上傳到Linux系統相應路徑后進行安裝。后續其他組件安裝遇此情況與此雷同,不再贅述):

[root@localhost ~]# cd /usr
[root@localhost usr]# wget http://download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.tar.bz2

解壓libgdiplus源碼安裝包:

[root@localhost usr]# tar jxvf libgdiplus-2.10.tar.bz2

配置libgdiplus組件安裝路徑(這里指定安裝路徑,是為后文產品化制作安裝包做准備,Mono、Jexus和MySQL安裝也是如此,不再贅述):

[root@localhost usr]# cd libgdiplus-2.10
[root@localhost libgdiplus-2.10]# ./configure --prefix=/usr/apollo/hostd/mono/

編譯libgdiplus源碼:

[root@localhost libgdiplus-2.10]# make

安裝libgdiplus組件:

[root@localhost libgdiplus-2.10]# make install

四、安裝Mono

Mono是Linux平台的.NET Framework實現,是.NET程序移植到Linux平台的不二選擇。首先,聯網下載Mono源碼安裝包:

[root@localhost libgdiplus-2.10]# cd /usr
[root@localhost usr]# wget http://download.mono-project.com/sources/mono/mono-4.0.4.1.tar.bz2

解壓Mono源碼安裝包:

[root@localhost usr]# tar jxvf mono-4.0.4.1.tar.bz2

配置Mono安裝路徑:

[root@localhost usr]# cd mono-4.0.4
[root@localhost mono-4.0.4]# ./configure --prefix=/usr/apollo/hostd/mono

編譯Mono源碼(此過程耗時一般為半小時到一小時,視系統軟硬件配置而定):

[root@localhost mono-4.0.4]# make

安裝Mono:

[root@localhost mono-4.0.4]# make install

通過查看Mono版本,確認Mono是否安裝成功(出現如下的版本信息表示Mono安裝成功):

[root@localhost mono-4.0.4]# cd /usr/apollo/hostd/mono/bin/
[root@localhost bin]# ./mono -V
Mono JIT compiler version 4.0.4 (Stable 4.0.4.1/5ab4c0d Fri Oct 30 06:56:35 CST 2015)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

五、安裝Jexus

Jexus是國人開發的Linux平台上的ASP.NET Web應用中間件,類似於Windows平台的IIS。實踐證明Jexus安裝簡單,運行穩定,是Linux平台架設ASP.NET應用的不錯選擇。首先,聯網下載Jexus安裝包:

[root@localhost ~]# cd /usr
[root@localhost usr]# wget http://www.linuxdot.net/down/jexus-5.6.5.tar.gz

解壓Jexus安裝包:

[root@localhost usr]# tar zxvf jexus-5.6.5.tar.gz

修改Jexus安裝路徑:

[root@localhost usr]# cd jexus-5.6.5
[root@localhost jexus-5.6.5]# vi install

#!/bin/sh

SRC_DIR=$(cd $(dirname $0);pwd)
DAT_DIR=${SRC_DIR}/data
JWS_DIR='/usr/apollo/hostd/jexus'

安裝Jexus:

[root@localhost jexus-5.6.5]# sudo ./install

修改Jexus關於mono路徑的配置:

[root@localhost jexus-5.6.5]# cd /usr/apollo/hostd/jexus
[root@localhost jexus]# vi jws

#!/bin/sh JWS_HOME=$(cd $(dirname $0);pwd)

export LANG="zh_CN.UTF-8" export PATH=/usr/bin:${JWS_HOME}/../mono/bin:$PATH export LD_LIBRARY_PATH=/usr/lib:${JWS_HOME}/../mono/lib:$LD_LIBRARY_PATH

啟動Jexus服務,測試Jexus安裝是否正確:

[root@localhost jexus]# ./jws start

設置Jexus服務開機自啟動,增加如下高亮行::

[root@localhost jexus]# vi /etc/rc.d/rc.local

touch /var/lock/subsys/local
/usr/apollo/hostd/jexus/jws start

修改該文件權限並重啟:

[root@localhost jexus]# chmod +x /etc/rc.d/rc.local

六、部署網站

創建網站目錄:

[root@localhost jexus]# cd /usr/apollo/
[root@localhost apollo]# mkdir webapps
[root@localhost apollo]# cd webapps/
[root@localhost webapps]# mkdir default
[root@localhost webapps]# cd default/
[root@localhost default]# touch index.html
[root@localhost default]# vi index.html

 

<html>
<head>
    <title>ASP.NET跨平台最佳實踐</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
ASP.NET跨平台最佳實踐,看到該頁面,表示你的第一個網站已成功部署到Linux系統。
</body>
</html>

修改Jexus網站配置:

[root@localhost default]# cd /usr/apollo/hostd/jexus/siteconf
[root@localhost siteconf]# vi default

######################
# Web Site: Default
########################################

port=80 root=/ /usr/apollo/webapps/default
hosts=*    #OR your.com,*.your.com
…

開放防火牆80端口: 

[root@localhost siteconf]# vi /etc/sysconfig/iptables # Firewall configuration written by system-config-firewall # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT

重啟iptables,使防火牆設置生效:

[root@localhost siteconf]# /etc/init.d/iptables restart

重啟Jexus服務:

[root@localhost siteconf]# /usr/apollo/hostd/jexus/jws restart

終端瀏覽器輸入網址http://ip:port/index.html訪問網站:

 

3 ASP.NET網站成功部署到Linux平台

七、數據庫

Linux平台免費關系數據庫首選當然是MySQL,首先下載MySQL源碼安裝包:

[root@localhost siteconf]# cd /usr
[root@localhost usr]# wget http://downloads.mysql.com/archives/get/file/mysql-5.1.72-linux-x86_64-glibc23.tar.gz

解壓MySQL源碼安裝包到指定目錄,並修改目錄名稱:

[root@localhost usr]# tar zxvf mysql-5.1.72-linux-x86_64-glibc23.tar.gz -C /usr/apollo
[root@localhost usr]# cd apollo
[root@localhost apollo]# mv mysql-5.1.72-linux-x86_64-glibc23 data

將mysql配置文件拷貝至指定目錄:

[root@localhost apollo]# cd data
[root@localhost data]# cp support-files/my-medium.cnf /etc/my.cnf

編輯mysql配置文件,在[client]節和[mysqld]節中加入以下高亮行::

[root@localhost data]# vi /etc/my.cnf

[client]
#password       = your_password
port            = 3306
socket          = /tmp/mysql.sock
default-character-set = utf8

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
skip-locking
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
basedir = /usr/apollo/data datadir = /usr/apollo/data/data character-set-server = utf8 collation-server = utf8_general_ci

創建mysql組及用戶,並設定目錄訪問權限:

[root@localhost data]# groupadd mysql
[root@localhost data]# useradd -g mysql mysql
[root@localhost data]# chown -R mysql .
[root@localhost data]# chgrp -R mysql .
[root@localhost data]# chown -R root .
[root@localhost data]# chown -R mysql data

初始化數據庫:

[root@localhost data]# scripts/mysql_install_db --user=mysql

運行mysql服務:

[root@localhost data]# bin/mysqld_safe --user=mysql &

這種方式啟動MySQL是阻塞式的,需要另開一個會話登錄Linux系統,繼續后續操作。

設置root用戶密碼:

[root@localhost data]# bin/mysqladmin -uroot password 11111111

設置mysql服務開機自動啟動:

[root@localhost data]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld
[root@localhost data]# chmod 700 /etc/init.d/mysqld
[root@localhost data]# chkconfig --add mysqld
[root@localhost data]# chkconfig --level 345 mysqld on

現在,可以停止之前會話啟動的MySQL服務(快捷鍵Ctrl + C),使用service命令后台啟動MySQL服務。

[root@localhost data]# service mysqld start

將mysql命令加入系統環境變量中,在文件末尾加上以下兩行代碼:

[root@localhost data]# vi /etc/profile


...
PATH=$PATH:/usr/apollo/data/bin export

執行配置,並重啟系統,讓環境變量生效:

[root@localhost data]# source /etc/profile

待Linux系統重啟后,MySQL服務可以自動啟動,MySQL命令也包含在了環境變量中。此時,MySQL服務已經可以在本地訪問了,可以通過MySQL命令行創建數據庫、執行SQL文件等操作。另外,可以通過MySQL命令行配置允許遠程訪問MySQL數據庫(當網站服務和MySQL數據庫服務在一起時,可以不進行該配置):

[root@localhost ~]# mysql -uroot -p11111111
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '11111111' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> exit;

還需要防火牆開放3306端口,編輯防火牆規則文件,在防火牆規則文件中添加如下高亮行:

[root@localhost ~]# vi /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

重啟防火牆服務:

[root@localhost ~]# /etc/init.d/iptables restart

此時可以遠程訪問MySQL數據庫了。

八、部署ASP.NET應用

本示例提供一個ASP.NET MVC應用,放置在后文制作的tar包webapps目錄下,該示例通過Entity Framework實現數據庫的自動創建及數據的增刪改查。將該目錄上傳至Linux系統的/usr/apollo/webapps目錄下,並配置Jexus網站配置:

[root@localhost ~]# cd /usr/apollo/hostd/jexus/siteconf/
[root@localhost siteconf]# cp default demo
[root@localhost siteconf]# vi demo


…
port=8080 root=/ /usr/apollo/webapps/demo
hosts=*    #OR your.com,*.your.com
…

Jexus支持承載多個Web站點,所以這里新增的demo站點和之前創建的default站點可以共存,僅需配置不同的端口號即可。同樣的需要開放防火牆8080端口:

[root@localhost siteconf]# vi /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

重啟iptables,使防火牆設置生效:

[root@localhost siteconf]# /etc/init.d/iptables restart

重啟Jexus服務:

[root@localhost siteconf]# /usr/apollo/hostd/jexus/jws restart

現在可以在終端通過瀏覽器訪問ASP.NET MVC站點了。

 

4 Linux環境部署ASP.NET MVC應用

產品化

通過上述一系列步驟,我們實現了ASP.NET MVC應用在Linux平台的部署,但這僅僅是技術預研,離產品化還有一定的距離。這一系列步驟技術性太強,需要聯網,不易操作,這些對於生產和用戶環境都是難於實現的。我們需要將.NET跨平台技術產品化,使得ASP.NET應用易於部署。

一、初始化腳本

如前文所述,ASP.NET應用在Linux平台部署需要設置防火牆策略、MySQL用戶與分組、Jexus與MySQL服務開機自啟動等,相當繁瑣。我們可以將這些設置集中在一個初始化腳本里執行。

#!/bin/sh

#echo off
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

#創建軟鏈接,以支持將應用部署到任意目錄
#ln -s -T $DIR /usr/apollo

#拷貝事先配置好的MySQL配置文件到指定目錄
cp -f $DIR/conf/my.cnf /etc/my.cnf

#創建MySQL需要的用戶和用戶組
groupadd mysql
useradd -g mysql mysql
chown -R root .
chown -R mysql data
chgrp -R mysql data

#設置MySQL服務開機自啟動
cp $DIR/data/support-files/mysql.server /etc/rc.d/init.d/mysqld
chmod 700 /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig --level 345 mysqld on

#將MySQL命令加入系統環境變量
sudo cat $DIR/conf/profile >> /etc/profile
source /etc/profile

#設置防火牆策略
cp -f $DIR/conf/iptables /etc/sysconfig/iptables

#設置Jexus服務開機自啟動
sudo cat $DIR/conf/rc.local >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
chmod a+x $DIR/hostd/jexus/jws
chmod a+x -R $DIR/hostd/mono/bin

#重啟系統
reboot

二、制作安裝包

將Linux平台部署ASP.NET應用需要的技術包括Mono、Jexus、MySQL等集成並進行打包分發。

[root@localhost ~]# tar jcvf crossplatform-1.0.0.0-centos6.4-x86_32_64.tar.bz2 /usr/apollo

三、通過安裝包部署ASP.NET應用

至此,Linux平台Web應用部署包已打好,將其下載到終端。將虛擬機恢復到初始安裝快照狀態,然后將終端上的部署包上傳到Linux系統中並解壓:

[root@localhost usr]# tar jxvf crossplatform-1.0.0.0-centos6.4-x86_32_64.tar.bz2

執行初始化腳本完成安裝:

[root@localhost usr]# cd apollo
[root@localhost apollo]# sh ./install

在終端通過瀏覽器訪問ASP.NET MVC站點,確認部署成功。

 

5 Linux平台產品化部署ASP.NET MVC應用

總結

本文詳細講解了Linux平台部署ASP.NET應用的最佳實踐過程,通過該實踐過程了解了ASP.NET應用跨平台部署的方方面面,該過程同樣適用於其他Linux分發版本和國產操作系統。另外,本文對Linux平台部署ASP.NET應用進行了產品化包裝,制作的安裝包可以直接應用於產品打包,你只需將應用放入指定目錄即可。希望本文所闡述的技術對你有所幫助。

 

附件下載:示例源碼+本文PDF版本

附件下載:產品化部署TAR包

 

其他最佳實踐建議(持續更新)

  1. Mono對ASP.NET WebForm技術支持還不是很好,盡量不要選擇ASP.NET WebForm技術,ASP.NET MVC技術是更好的選擇;
  2. Mono似乎暫時不支持ValidateInputAttribute,所以如果你的Action需要禁用輸入參數驗證,需要在Web.config中增加“<httpRuntime requestValidationMode="2.0"/>”全局配置;
  3. Mono似乎暫時不支持BundleConfig,所以不要用這種方式來綁定前台資源;
  4. 如果你用了Sping.NET IoC技術,你一定會愛上她針對ASP.NET MVC Controller的自動注入功能,但是目前在Mono上運行有問題,原因暫未查明,只能舍棄而改用傳統的IObjectFactory.GetObject方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM