電子郵件服務(wù)原理與搭建

引言

最近在為一個海事項(xiàng)目內(nèi)網(wǎng)環(huán)境搭建郵件服務(wù)器,對郵件服務(wù)的原理和流程有了更深的認(rèn)識與梳理。
說起電子郵件毡熏,最容易想到的就是使用B/S架構(gòu)的gmail舍扰、163倦蚪、QQ郵箱收發(fā)郵件了。但對于一個企業(yè)內(nèi)部而言边苹,往往不會采用這些第三方公司開放的郵箱應(yīng)用和服務(wù)陵且,這主要是出于對信息保密、靈活定制、維護(hù)方便慕购、存儲空間等方面的考慮聊疲,因此越來越多的企業(yè)都開始自己搭建電子郵件服務(wù),使得內(nèi)部員工可以在同一個內(nèi)網(wǎng)下使用沪悲。
本文首先簡單介紹下郵件服務(wù)器的工作原理與相關(guān)協(xié)議获洲,再實(shí)際記錄下采用開源項(xiàng)目Apache James(Java Apache Mail Enterprise Server)搭建郵件服務(wù)器的過程與關(guān)鍵點(diǎn)。

工作原理

郵件服務(wù)器其實(shí)是若干構(gòu)件的一個統(tǒng)稱殿如,具體細(xì)化后其實(shí)是由用戶代理贡珊、發(fā)送服務(wù)器、接收服務(wù)器涉馁、郵件發(fā)送協(xié)議(SMTP)门岔、郵件接收協(xié)議(POP3)組成的,如下圖所示烤送。


發(fā)件流程
  1. 發(fā)件人借助用戶代理(客戶端軟件寒随,如outlook、網(wǎng)頁版QQ郵箱)起草郵件帮坚,點(diǎn)擊發(fā)送郵件
  2. 用戶代理與發(fā)送服務(wù)器建立TCP可靠連接
  3. 用戶代理(充當(dāng)STMP客戶)以STMP協(xié)議承載傳輸至發(fā)送服務(wù)器(充當(dāng)STMP服務(wù)器)
  4. 發(fā)送服務(wù)器收到郵件后將他們暫存到一個郵件緩沖隊(duì)列中妻往,保證后續(xù)傳輸?shù)竭_(dá)順序的正確性
  5. 發(fā)送服務(wù)器與目的接收服務(wù)器建立TCP可靠連接
    6.發(fā)送服務(wù)器(這次充當(dāng)STMP客戶)依次摘取郵件緩沖隊(duì)列隊(duì)首郵件,再同樣以STMP協(xié)議經(jīng)網(wǎng)絡(luò)傳輸至接收方IP下的接收服務(wù)器(充當(dāng)STMP服務(wù)器)
收件流程
  1. 收件人打開用戶代理(客戶端軟件)并建立與接收服務(wù)器的TCP可靠連接
  2. 用戶代理使用POP3(IMAP)協(xié)議從接收服務(wù)器中讀取郵件數(shù)據(jù)
  3. 將讀取到的郵件數(shù)據(jù)呈現(xiàn)到客戶端界面上
  4. 當(dāng)然如果要求更完備一些的話试和,比如若要允許收發(fā)外域郵件蒲讯,那么還要涉及5.DNS服務(wù)器進(jìn)行域名解析,若要保證在客戶端對郵件的操作結(jié)果都時刻同步至服務(wù)器灰署,那么還要涉及IMAP交互式郵件存取協(xié)議等等判帮。

搭建流程

由上已經(jīng)知道,郵件服務(wù)器的核心是用戶代理溉箕、發(fā)送/接收服務(wù)器及它們之間通信的協(xié)議晦墙,因此在搭建時我采用了一個開源的B/S架構(gòu)的Web客戶端工程作為用戶代理,還有一個開源的Apache James基于Spring3.x而寫的郵件服務(wù)工程作為郵件服務(wù)器肴茄,他們都是基于Java語言編寫的晌畅。本文的搭建都是在CentOS 6.3系統(tǒng)上進(jìn)行的,搭建過程涉及JDK安裝寡痰、Tomcat安裝抗楔、MySQL安裝、Web服務(wù)部署拦坠、James服務(wù)部署连躏。下面依次記錄這幾個過程及遇到的問題。

1.JDK安裝

Web端的Java環(huán)境采用的是jdk1.8.0_131版本贞滨,通過從官網(wǎng)下載該版本的tar.gz包入热,解壓到lib目錄并配置環(huán)境變量,具體命令如下:

#解壓jdk
cd /usr/lib/java
tar -zvxf jdk1.8.0_131.tar.gz #事先將壓縮包放于此目錄
#配置環(huán)境變量
vi /etc/profile
export JAVA_HOME=/usr/share/jdk1.8.0_131 
export PATH=$JAVA_HOME/bin:$PATH 
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
2.Tomcat安裝

Tomcat作為Web服務(wù)的容器應(yīng)該已經(jīng)是約定俗成的傳統(tǒng)了,雖然有更輕量級的Jetty勺良,但其啟動命令很長讓我覺得很不優(yōu)雅所以不怎么愛用绰播。搭建很簡單,也是從官網(wǎng)下載Tomcat8(與jdk版本保持一致)的tar.gz包尚困,然后解壓到/usr/local目錄蠢箩,具體命令如下:

#解壓tomcat
cd /usr/local
tar -zvxf apache-tomcat-8.5.16.tar.gz #事先將壓縮包放于此目錄
#重命名
mv apache-tomcat-8.5.16 tomcat
#修改tomcat的java環(huán)境
cd /usr/local/tomcat/bin
vi catalina.sh
export JAVA_HOME=/usr/lib/java/jdk1.8.0_131
vi setclasspath.sh
export JAVA_HOME=/usr/lib/java/jdk1.8.0_131
#啟動
cd /usr/local/tomcat/bin 
./startup.sh
#停止
./shutdown.sh
3.MySQL安裝

數(shù)據(jù)庫采用MySQL,安裝過程采用yum事甜,先下載安裝包源并安裝源寿酌,然后安裝MySQL坟乾,命令如下:

# 下載mysql源安裝包
shell> wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
# 安裝mysql源
shell> yum localinstall mysql57-community-release-el7-8.noarch.rpm
#檢查mysql源是否安裝成功
yum repolist enabled | grep "mysql.*-community.*"
#安裝MySQL
yum install mysql-community-server
#啟動
service mysqld start
#停止
service mysqld stop

root用戶的初始密碼自動生成再了/var/log/mysqld.log下往产,我們對該密碼進(jìn)行更改方便后續(xù)使用溺蕉,命令如下:

#抓取root初始密碼
grep 'temporary password' /var/log/mysqld.log
#修改密碼
mysql -uroot -p
set password for 'root'@'localhost'=password('Grenade2017~');

但是之后搭建好Web服務(wù)和James服務(wù)后奏属,我們發(fā)現(xiàn)了兩個問題跨跨。第一個是插入漢字的時候在數(shù)據(jù)庫中會變成???,這個問題比較明確囱皿,解決辦法是在/etc/my.cnf文件中的[mysqld]與[client]下加上配置勇婴,命令如下:

vi /etc/my.cnf
#[mysqld]下加入
character-set-server=utf8
#[client]下加入
default-character-set=utf8

若是采用jdbc連接的數(shù)據(jù)庫,也可以在jdbc的配置文件對應(yīng)數(shù)據(jù)庫的那行加上編碼配置:

jdbc:mysql://localhost:3306/email?useUnicode=true&characterEncoding=UTF-8

另一個問題比較隱秘但也跟蹤出來了嘱腥,就是Web端在訪問表名的時候隨意采用大小寫耕渴,一會兒大寫,一會兒小寫齿兔,一會兒駝峰橱脸,部署在Windows系統(tǒng)上時沒有問題,但一旦拿到linux下就出表名相關(guān)的問題分苇。這是因?yàn)閃indows平臺上的MySQL數(shù)據(jù)庫對表名大小寫不敏感添诉,而Linux系統(tǒng)對數(shù)據(jù)庫表名大小寫敏感。解決辦法很簡單医寿,同樣是在/etc/my.cnf文件的[mysqld]下加入配置栏赴,命令如下:

#[mysqld]下加入
lower_case_table_names = 1 # 0/默認(rèn):敏感 1:不敏感
4.Web服務(wù)部署

Web工程是采用SSH(Spring-Struts-Hibernate)編寫的,需要的jar包都已經(jīng)引入了靖秩,所以在部署的時候我們只需要打好war包放在tomcat的webapps目錄下即可须眷。但在打war包之前記得將數(shù)據(jù)庫配置文件jdbc.properties中的連接信息替換成自己的:

jdbc.url=jdbc\:mysql\://localhost\:3306/email
jdbc.username=root
jdbc.password=123456
5 James服務(wù)部署

Apache James(Java Apache Mail Enterprise Server)是Apache組織的子項(xiàng)目之一,完全采用純Java技術(shù)開發(fā)沟突,實(shí)現(xiàn)了SMTP花颗、POP3與NNTP等多種郵件相關(guān)協(xié)議。James也是一個郵件應(yīng)用平臺惠拭,可以通過Mailet擴(kuò)充其功能捎稚,如Mail2SMS、Mail2Fax等。James提供了比較完善的配置方案今野,尤其是關(guān)于郵件內(nèi)容存儲和用戶信息存儲部分葡公,可以選擇在文件、數(shù)據(jù)庫或其他介質(zhì)中保存条霜。更多詳情可參見Apache James Project催什。本文僅給出James服務(wù)工程的配置與部署過程,包括如下幾個步驟宰睡。

1) 數(shù)據(jù)庫修改

James工程的conf目錄下有一個database.properties配置文件蒲凶,可對其中的數(shù)據(jù)庫信息進(jìn)行配置以適應(yīng)部署時的生產(chǎn)環(huán)境,如下所示:

database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/email
database.username=root
database.password=123456
vendorAdapter.database=MYSQL
openjpa.streaming=false
2) 不依賴外網(wǎng)

如果不做任何修改拆内,在默認(rèn)情況下啟動James服務(wù)旋圆,會報無法訪問外網(wǎng)的錯誤(在spring-beans.xml文件中)。這個問題是因?yàn)镴ames基于Spring3.x麸恍,會采用XML文件進(jìn)行一些beans的配置灵巧,而XML文件格式、語法抹沪、結(jié)構(gòu)等方面正確性的驗(yàn)證又依賴于XSD文件(XML Schemas Definition)刻肄。而spring-beans.xml中配置的XSD文件是通過HTTP協(xié)議訪問外網(wǎng)服務(wù)器上的資源得到的,我們需要把訪問路徑改為本地XSD文件所在的路徑(剛好包含于對應(yīng)的jar包中)融欧。修改如下所示:

<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:amq="http://activemq.apache.org/schema/core" 
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd
          http://camel.apache.org/schema/spring classpath:/camel-spring.xsd
          http://activemq.apache.org/schema/core classpath:/activemq.xsd">
3) 后臺啟動

James服務(wù)的啟動很簡單敏弃,進(jìn)入bin目錄,輸入下面命令:

cd /usr/local/james/bin
./run.sh

但這樣做存在一個問題:因?yàn)橥ǔN覀儾捎胹sh遠(yuǎn)程訪問服務(wù)器噪馏,當(dāng)啟動服務(wù)后只要關(guān)閉終端麦到,James服務(wù)對應(yīng)的進(jìn)程也會退出。因此我們需要在命令末尾加上&保證是后臺啟動欠肾,不占用終端界面進(jìn)程:

./run.sh &

但這樣做以后會發(fā)現(xiàn)退出終端后進(jìn)程還是斷了隅要,網(wǎng)上查了一番后才發(fā)現(xiàn),原來真正的后臺啟動需要采用nohup命令董济,它可以忽略掛起步清、退出等信號,如下所示:

nohup ./run.sh &

結(jié)語

本文僅是對電子郵件服務(wù)的基本原理和搭建給出了一個大概的整理虏肾,但仍然缺少對郵件服務(wù)器更底層原理性東西的闡述廓啊,如SMTP協(xié)議、POP3協(xié)議封豪、服務(wù)器推技術(shù)等谴轮,若感興趣可以查閱相關(guān)資料進(jìn)行閱讀。
關(guān)于本文用到的兩個工程的代碼可以在我的GitHub中的email倉庫下載吹埠,其中文件夾james-server-container-spring-3.0-M2就是James工程第步,剩余部分都是Web端工程的內(nèi)容疮装,可導(dǎo)入到idea/eclipse打成war包部署。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末粘都,一起剝皮案震驚了整個濱河市廓推,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翩隧,老刑警劉巖樊展,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堆生,居然都是意外死亡专缠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門淑仆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涝婉,“玉大人,你說我怎么就攤上這事蔗怠《胀洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵蟀淮,是天一觀的道長。 經(jīng)常有香客問我钞澳,道長怠惶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任轧粟,我火速辦了婚禮策治,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兰吟。我一直安慰自己通惫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布混蔼。 她就那樣靜靜地躺著履腋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惭嚣。 梳的紋絲不亂的頭發(fā)上遵湖,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音晚吞,去河邊找鬼延旧。 笑死,一個胖子當(dāng)著我的面吹牛槽地,可吹牛的內(nèi)容都是我干的迁沫。 我是一名探鬼主播芦瘾,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼集畅!你這毒婦竟也來了近弟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牡整,失蹤者是張志新(化名)和其女友劉穎藐吮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逃贝,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谣辞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了沐扳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泥从。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖沪摄,靈堂內(nèi)的尸體忽然破棺而出躯嫉,到底是詐尸還是另有隱情,我是刑警寧澤杨拐,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布祈餐,位于F島的核電站,受9級特大地震影響哄陶,放射性物質(zhì)發(fā)生泄漏帆阳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一屋吨、第九天 我趴在偏房一處隱蔽的房頂上張望蜒谤。 院中可真熱鬧,春花似錦至扰、人聲如沸鳍徽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阶祭。三九已至,卻和暖如春直秆,著一層夾襖步出監(jiān)牢的瞬間胖翰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工切厘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留萨咳,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓疫稿,卻偏偏與公主長得像培他,于是被迫代替她去往敵國和親鹃两。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容