標籤: 租車

  • Gogoro擴點台中南投屏東,全台將有360個換電站

    Gogoro擴點台中南投屏東,全台將有360個換電站

    徹底改寫電動機車市場銷售紀錄的新創公司Gogoro,在短短兩年內已突破20,000 輛的銷售數字,並建置了300 多個電池交換站,充分展現了積極搶攻市場版圖的超高效率與決心。Gogoro 13 日宣布,將在4 月底開始投入在台中海線的3 個城鎮以及屏東地區首座換電站的設置;5 月底前則將進入南投。

    Gogoro 能源服務副總經理潘璟倫表示,Gogoro 在第一季的布站目標主要著力在高雄及台南地區,共於該區新增了19 個換電站。第二季,則會強化在六都以外的建置計畫,除預計在屏東市、東港、南投市、草屯、員林等地設置首座換電站外,也會在清水,沙鹿,大甲與鹿港4 個城鎮分別設置換電站以串連、打通台中彰化的海線。Gogoro 最南端的換電站,也預期在第二季末於東港設立。這些都是依據大數據分析的結果所進行的計畫,後續,大家也可以很快地可以看到在不同的區域,看到GoStation 電池交換站。

    在六都地區,Gogoro 仍以「一公里一座換電站」為能源網路目標,從北台灣一路往南延伸,透過與加油站、捷運站、學校、便利商店、賣場等單位異業結盟,合作布點的方式,積極擴大台灣綠色生活圈。

    依照Gogoro 第二季的計畫,6 月底前,全台將會有360 個換電站。這讓Gogoro 更貼近其將在2017 年底完成西岸走廊串連,讓基隆到屏東的西部都會區得以北南縱走,暢騎無阻的承諾。

    (合作媒體:。圖片出處:Gogoro)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

  • Model3加速趕工略程序,冒日後召回維修風險

    Model3加速趕工略程序,冒日後召回維修風險

     

    特斯拉(Tesla Inc)正在加速趕工,希望能在2017年9月讓平價電動車「Model 3」如期投產,但執行長馬斯克(Elon Musk)為了達標、在生產策略上背負不小風險,未來可能會面臨召回、維修等龐大成本。

    路透社24日報導(),大多數的汽車製造商都會先訂購較便宜的原型設備來測試新車款的生產線,一旦成功打造出合適的車門、儀表板等零組件,就會把這些便宜的設備報廢。

    然而,特斯拉在打造Model 3時卻跳過這項程序,直接訂購較為昂貴的永久設備加速趕工,目標就是趕上自己設定的9月量產期限。不過,用來量產數百萬輛汽車的設備假如無法順利製造出合適的零件,想要修正或直接替代,都得花費大把資金。特斯拉現有的車種產量雖少,卻已在品質方面出現問題,Model 3預設的年產量多達50萬台,一旦需要召回或進行保固期維修,都會拉高公司成本。

    馬斯克3月份在一場法說會曾討論過這個問題。他當時說,利用「先進的分析技術」(即電腦模擬科技的代稱),就能幫助特斯拉直接進入安裝設備的階段。

    的確,福斯(Volkswagen AG)旗下的奧迪(Audi)部門,已經領先業界在墨西哥新建廠房採用生產工具的電腦模擬科技,讓初步投產的時間,比一般流程快了30%。當時參與奧迪墨西哥廠投產流程的經理Peter Hochholdinger,如今已成為特斯拉生產部門的副總裁。除此之外,特斯拉在2015年收購一家密西根設備業者後,也學到更佳的設備修整技術,不但讓製造大型機具的速度加快30%、成本還能壓得更低。

    話雖如此,特斯拉自2003年成立以來就面臨龐大的金融壓力,雖然3月的12億美元募資行動、以及將5%股權賣給騰訊(Tencent Holdings Ltd),讓公司喘了一口氣,但若是Model 3生產不順,後果堪慮。

    CNET、路透社等多家外電報導,特斯拉甫於4月20日宣布在全球召回53,000輛Model S、Model X電動車,以便修正電子手煞車的問題。

    特斯拉在聲明中表示,受到影響的是在2016年2月至10月期間生產的Model S與Model X,這些汽車的電子手煞車當中,有一款由第三方廠商供應的小型零組件因製造不當而容易裂開,會讓手煞車無法解除。

    特斯拉強調,上述瑕疵至今並未引發任何車禍、也未導致人員死傷,估計這些車輛中,只有不到5%有問題,更換手煞車的時間僅需不到45分鐘。根據聲明,特斯拉正在跟義大利供應商Freni Brembo SpA合作,取得需要更替的零組件。

    (本文內容由授權使用。圖片出處:Tesla)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

    FB行銷專家,教你從零開始的技巧

  • Tesla擴大充電網絡規模,供卓越充電體驗

    Tesla擴大充電網絡規模,供卓越充電體驗

    隨著Tesla 準備生產首款因應大眾市場的車型,Model S、Model X 的產量持續擴大,為客戶提供卓越的充電體驗成為Tesla 的首要目標。為現在和未來的車主提供便捷、豐富、可靠的充電服務對我們以及公司的使命至關重要。2017 年,Tesla 全球充電網絡規模將擴大一倍,並對現有的充電站進行擴建, 讓駕駛不必排隊等候充電;同時,我們還將擴大市中心區域的充電站 覆蓋。

    一直以來,最便捷的充電方式都是夜間在停車位充電。為了更好的服務出門在外以及缺乏穩定家用充電設備的車主,我們將繼續大舉擴建Tesla 公共充電網絡。自2012 年Tesla 超級充電站網絡投入使用至今,Tesla 已經建造了5,400 多個超級充電座, 目的是讓全球20 多萬Tesla 車主都能方便地進行長途旅行。此外,我們還建立了一個已擁有9,000 多個目的地充電座的充電網絡,通過在酒店、度假村、餐廳等場所安裝Tesla 壁掛式充電座,為車主提供如同在家一般的便捷舒適的充電體驗。但我們知道, 要想真正推動電動車的普及,我們必須繼續投資建設充電基礎設施。

    2017 年初,全球已經有5,000 多個Tesla 超級充電座;截至今年年底,Tesla 將把這個數量擴大一倍,超級充電座總數將突破1 萬個,目的地充電座總數增至約1.5 萬個。北美地區的超級充電座數量將增至現有的1.5 倍,僅加州就將增設超過1,000 個超級充電座。選址工作已經開始,新的充電站很快將投入建設,並於今年夏天旅行季節到來之前投入使用。

    為此,我們將沿著最繁忙的行駛路線建設規模更大的充電站,這些道路沿線將同時出現數十座Tesla 超級充電站。此外,我們還將在距離公路較遠的地帶增設多個充電站,讓當地Tesla 駕駛可以隨需隨充,從而實現市中心隨處皆可充電的目標。

    憑藉全球領先、便捷的充電技術,不斷打造獨一無二、充分利用此充電技術的電動車,Tesla 長期以來一直引領全球電動車產業的發展。充電網絡的不斷擴展將確保Tesla 駕駛在任何情況下都能快速、便捷地為車輛充電,而這正是Tesla 工作的首要目標。

    針對台灣,目前已完成架構超過160 座目的地充電站,以及位於台北花博的6 座超級充電站。Tesla 預計於2017 年中完成超過200 座的目的地充電站,分佈於全台超過50 個地點。同時,車主高度期待位於中部、南部的超級充電站也預計同樣於年中完成建置。如此一來,Tesla 車主即可毫無顧慮的完成全島南北往返的長途旅行。針對如此的長途旅行,不僅是都會區,Tesla 也在各個熱門景點附近的飯店設立目的地充電站,以便車主旅途中隔夜充電使用。

    (合作媒體:。圖片出處:Steve Jurvetson via Flickr CC2.0)  

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※超省錢租車方案

    ※教你寫出一流的銷售文案?

    網頁設計最專業,超強功能平台可客製化

  • 台達電佈局電動車產品,拓歐美電動車市場

    台達電佈局電動車產品,拓歐美電動車市場

    台達電於4月28日舉行法說會,公佈2017年第一季財報合併營收489.25億元新台幣,季減14%,年增2.8%;毛利率27.2%,季減0.06個百分點,年增0.26個百分點;因管控得宜,第一季匯兌收益1.4億元;稅後淨利39.19億元,每股盈餘1.51元,低於前一季的1.91元,略高於去年同期的1.50元。

    台達電執行長鄭平表示,公司5月起進行組織調整,擴大在電動車相關產品佈局,目前公司已打入歐美電動車廠,提供包括車載充電器、動力馬達、DC-DC轉換器等電動車零組件;在中國大陸也打入合資車廠,雖然電動車領域營收短期內成長幅度不大,但仍看好電動車領域未來長期的布局效益。

    台達電宣布組織調整,自2日起,將以「電源及零組件」、「自動化」與「基礎設施」為新三大業務範疇,其中,電源及零組件業務包括電動車方案事業群(EVSBG)、嵌入式電源系統事業群(EPSBG)、商用電源事業群(MPBG)、零組件事業群(CPBG)、風扇暨熱傳導事業群(FMBG);自動化業務包括機電事業群(IABG)、樓宇自動化事業群(BABG);至於基礎設施業務則包括資通訊基礎設施事業群(ICTBG)、能源基礎設施事業群(EISBG)。以新三大業務範疇區分,第一季電源及零組件占營收比重為55%、自動化占比為11%,基礎設施則占31%。

    對於未來營運展望,台達電董事長海英俊表示,第二季看好IA、樓宇自動化、數據中心的營運動能;今年雖然有匯率變數,但強調公司營運不會受到影響,並將持續朝向高毛利產品發展,讓毛利率能維持目前水準或更好。

    (本文內容由授權使用)  

     

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※教你寫出一流的銷售文案?

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 自動化主管請辭Tesla,市場憂電動車量產計畫

    自動化主管請辭Tesla,市場憂電動車量產計畫

    特斯拉(Tesla Inc.)負責自動化、工程專業的主管Klaus Grohmann,傳出因理念和執行長馬斯克(Elon Musk)不合,已經在3月份離職。市場擔憂,這恐怕會影響特斯拉電動車的量產計畫。

    路透社27日獨家報導(),特斯拉在2016年11月收購Grohmann創辦的Grohmann Engineering,原本打算靠著這家企業的自動化、工程專長,在2018年將電動車年產量拉升至50萬台。

    不過,消息人士透露,Grohmann跟馬斯克在如何對待現有客戶的問題上衝突不斷,是促使Grohmann離職的主因。據傳,馬斯克要求Grohmann把重心擺到特斯拉專案,將Grohmann Engineering原有客戶(如戴姆勒和BMW)的利益放到後頭。

    消息稱,特斯拉仍計畫運用Grohmann留下的技術和人員拉高產能,但部分人在創辦人離開後,對只仰賴一家客戶(也就是特斯拉)的作法感到相當不安。

    特斯拉正在加速趕工,希望能在2017年9月讓平價電動車「Model 3」如期投產,但馬斯克為了達標、在生產策略上背負不小風險,未來可能會面臨召回、維修等龐大成本。

    路透社4月24日報導,大多數的汽車製造商都會先訂購較便宜的原型設備來測試新車款的生產線,一旦成功打造出合適的車門、儀表板等零組件,就會把這些便宜的設備報廢。

    然而,特斯拉在打造Model 3時卻跳過這項程序,直接訂購較為昂貴的永久設備加速趕工,目標就是趕上自己設定的9月量產期限。不過,用來量產數百萬輛汽車的設備假如無法順利製造出合適的零件,想要修正或直接替代,都得花費大把資金。Model 3預設的年產量多達50萬台,一旦需要召回或進行保固期維修,都會拉高公司成本。

    CNET、路透社等多家外電報導,特斯拉甫於4月20日宣布在全球召回53,000輛Model S、Model X電動車,以便修正電子手煞車的問題。

    特斯拉在聲明中表示,受到影響的是在2016年2月至10月期間生產的Model S與Model X,這些汽車的電子手煞車當中,有一款由第三方廠商供應的小型零組件因製造不當而容易裂開,會讓手煞車無法解除。

    特斯拉強調,上述瑕疵至今並未引發任何車禍、也未導致人員死傷,估計這些車輛中,只有不到5%有問題,更換手煞車的時間僅需不到45分鐘。根據聲明,特斯拉正在跟義大利供應商Freni Brembo SpA合作,取得需要更替的零組件。

    (本文內容由授權使用。圖片出處:public domain CC0)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

    ※教你寫出一流的銷售文案?

    FB行銷專家,教你從零開始的技巧

  • 圖像處理中的valid卷積與same卷積

    valid卷積

    在full卷積的卷積過程中,會遇到\(K_{flip}\)靠近I的邊界(K矩陣與I矩陣),就會有部分延申到I之外,這時候忽略邊界,只考慮I完全覆蓋\(K_{flip}\)內的值情況,這個的過程就是valid卷積。一個高為H1,寬為W1的矩陣I與高為H2,寬為W2的矩陣K,在H1大於等於H2,W1大於等於W2的情況下,valid卷積的結果就是一個(H1-H2+1)*(W-W+1)的矩陣\(C_{valid}\)

    \[C_{valid}與C_{full}的對應關係為: C_{valid} = C_{full}( Rect (W_{2}-1,H_{2}-1,W_{1}-W_{2}+1,H_{1}-H_{2}+1) ) \]

    same卷積

    無論是full卷積還是valid卷積都不會得到正好的尺寸,要麼比原尺寸大要麼比原尺寸小,這時就需要same卷積來解決這個問題。若想得到寬和高都正好的矩陣我們首先需要給\(K_{flip}\)一個錨點,將錨點放在(循環)圖像矩陣的(r,c)處,((r,c)在矩陣之內),將對應位置的元素逐個相乘,最終將所有的積進行求和作為輸出圖像矩陣在(r,c)處的輸出值。這個過程稱為same卷積。
    OpenCv函數copyMakeBorder的參數表

    參數 解釋
    src 輸入矩陣
    dst 輸出矩陣
    top 上側擴充的行數
    bottom 下側擴充的行數
    left 左側擴充的行數
    right 右側擴充的行數
    borderType 邊界擴充的類型
    value border Type= BORDER_CONSTANT事的常數

    其中borderType有多種類型,比如:BORDER_REPLICATE(邊界複製)、BORDER_CONSTANT(常數擴充)、BORDER_REFLECT(反射擴充)等。
    在使用Python進行卷積操作時用到包Scipy,其中有關的操作函數為convolve2d(in1,in2,mode=’full’,boundary=’fill’,fillvalue=0)

    參數 解釋
    in1 輸入數組
    in2 輸入數組,代表K(卷積算子)
    mode 卷積類型,也就是以上提到的三種類型:full,valid,same
    boundary 邊界填充:fill\wrap\symm
    fillvalue 當boundary=’fill’時,設置邊界填充的值,默認為0

    在這裏需要注意的是當model為same時卷積算子的錨點位置由不同尺寸而不同,假設K(卷積算子)的寬和高分別為W、H。

    W和H的值 錨點位置
    均為奇數 默認為中心點
    H為偶數、W為奇數 (H-1,(W-1)/2)
    H為奇數,W為偶數 ((H-1)/2,W-1)
    均為偶數 (H-1,W-1)

    代碼實現:

    import numpy as np
    from scipy import signal
    
    if __name__ == "__main__":
    
        I = np.array([[1,2],[3,4],np.float32])
        #I的高和寬
        H1,W1 = I.shape[:2]
        #卷積算子
        k = np.array([[-1,-2],[2,1],np.float32])
        #K的寬和高
        H2,W2 = k.shape[:2]
        #計算full卷積
        c_full = signal.convolve2d(I,k,mode='full')
        #設定錨點
        r,c = 0,0
        #根據錨點來從full卷積中截取same卷積
        c_same= c_full[H2-r-1:H1-r-1,W2-c-1:W1+W2-c-1]
    

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

  • Java Jar 包加密 — XJar

    Java Jar 包加密 — XJar

    Java Jar 包加密

    一、緣由

      Java的 Jar包中的.class文件可以通過反彙編得到源碼。這樣一款應用的安全性就很難得到保證,別人只要得到你的應用,不需花費什麼力氣,就可以得到源碼。

      這時候就需要對jar進行加密處理。

    二、技術&工具

      XJar

      GitHub:https://github.com/core-lib/xjar

      碼雲:https://gitee.com/core-lib/xjar?_from=gitee_search

      maven集成 XJar

     

      GitHub:https://github.com/core-lib/xjar-maven-plugin

      碼雲:https://gitee.com/core-lib/xjar-maven-plugin?_from=gitee_search

      xjar-agent-hibernate

      GitHub:https://github.com/core-lib/xjar-agent-hibernate

      碼雲:https://gitee.com/core-lib/xjar-agent-hibernate?_from=gitee_search

      go語言、maven、eclipse

      文檔可以到github、碼雲上去了解,這裏只描述使用過程,親測可用!

    三、實現過程

      這裏使用的maven版本是:apache-maven-3.6.3,低版本的沒測試過

      1、XJar

       1-1.在github或碼雲上下載該項目,導入eclipse,然後新建一個main類,填入參數,直接運行得到一個xjar.go 和 加密后的jar包【xx-encrypted.jar】。

        注意:這種直接在項目中跑mian,不提倡,會導致jar包中包含這段代碼,導緻密碼泄露,所以要通過命令行的方式來執行這段代碼。

        

        1-2.這時候可以用反編譯軟件 jb-gui 打開jar看看加密的效果,這時候反編譯軟件已經看不到.class文件的源碼了

     

     

         1-3.加密后的jar包,不能直接用原來的java 命令來執行,需要用到同時生成的xjar.go文件,執行命令 go build xjar.go

          這裏要等待一小會,等待編譯出目標文件xjar.exe

          

     

     

           

          1-4. 最後執行命令,xjar java -jar /path/to/encrypted.jar,即可運行加密后的jar包

           注意:Spring Boot + JPA(Hibernate) 啟動會報錯

                       1-5:沒有採用 Spring Boot + JPA(Hibernate) 技術的可以略過以下步驟。

          a、到碼雲、GitHub上下載  xjar-agent-hibernate  項目

          b、導入eclipse 打包出jar包

          c、然後執行命令  xjar java -javaagent:xjar-agent-hibernate-v1.0.0.jar -jar path\wx-encrypted.jar,即可正常運行

          

       2、maven集成 XJar

        第二種方式就比較簡單了,直接在項目中引入xjar-maven-plugin,然後打包就可以了,其他操作方式和第一種類似

        注意:密碼最好採用命令行方式

    <pluginRepositories>
      <pluginRepository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
      </pluginRepository>
    </pluginRepositories>

           

     <plugin> <groupId>com.github.core-lib</groupId> <artifactId>xjar-maven-plugin</artifactId> <version>4.0.0</version> <executions> <execution> <goals> <goal>build</goal> </goals> <phase>install</phase> <configuration> <password>1233445</password> <includes>
                       <!----> <include>/com/xxx/xxx/**/*.class</include> </includes> <!-- 無需加密的資源路徑表達式 --> <excludes> <exclude>static/**</exclude> <exclude>META-INF/resources/**</exclude> </excludes> <!-- 源jar所在目錄 --> <sourceDir>path\</sourceDir> <!-- 源jar名稱 --> <sourceJar>xxx.jar</sourceJar> <!-- 目標jar存放目錄 --> <targetDir>path\test2</targetDir> <!-- 目標jar名稱 --> <targetJar>xxx-encrypted.jar</targetJar> </configuration> </execution> </executions> </plugin>

    四、後記

      其實所有軟件,都可以被破解,只是破解過程是簡單還是複雜、以及破解成本的高低。

      最關鍵的還是自己軟件要更新迭代的快,這樣才能把模仿者遠遠甩在身後。

      轉發請註明出處!!!

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

    FB行銷專家,教你從零開始的技巧

  • 程序員必須掌握的Java 框架,小白學會之後15k不是問題

    程序員必須掌握的Java 框架,小白學會之後15k不是問題

    Spring 的核心特性是什麼?Spring 優點?

    Spring 的核心是控制反轉(IoC)和面向切面(AOP)

    Spring 優點:

    程序員必須掌握的Java 框架,學會之後50k不是問題
    (1)方便解耦,簡化開發 (高內聚低耦合)

    Spring 就是一個大工廠(容器),可以將所有對象創建和依賴關係維護,交給 Spring管理

    spring 工廠是用於生成 bean

    (2)AOP 編程的支持

    Spring 提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能

    (3) 聲明式事務的支持

    只需要通過配置就可以完成對事務的管理,而無需手動編程

    (4) 方便程序的測試

    Spring 對 Junit4 支持,可以通過註解方便的測試 Spring 程序

    (5)方便集成各種優秀框架

    Spring 不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持

    (6) 降低 JavaEE API 的使用難度

    Spring 對 JavaEE 開發中非常難用的一些 API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些 API 應用難度大大降低

    spring 框架中需要引用哪些 jar 包,以及這些 jar 包的用途

    4 + 1 : 4 個 核 心 ( beans 、 core 、 context 、 expression ) + 1 個 依 賴(commons-loggins…jar)

    理解 AOP、IoC 的基本原理;

    IOC:控制反轉(IoC)與依賴注入(DI)是同一個概念,

    控制反轉的思想:

    傳統的 java 開發模式中,當需要一個對象時,我們會自己使用 new 或者getInstance 等直接或者間接調用構造方法創建一個對象。而在 spring 開發模式中,spring 容器使用了工廠模式為我們創建了所需要的對象,不需要我們自己創建了,直接調用 spring 提供的對象就可以了

    引入 IOC 的目的:

    (1)脫開、降低類之間的耦合;(2)倡導面向接口編程、實施依賴倒換原則;

    (3)提高系統可插入、可測試、可修改等特性

    AOP:面向切面編程(AOP)面向切面編程思想:

    在面向對象編程(oop)思想中,我們將事物縱向抽成一個個的對象。而在面向切面編程中,我們將一個個的對象某些類似的方面橫向抽成一個切面,對這個切面進行一些如權限控制、事物管理,記錄日誌等公用操作處理的過程。

    切面:簡單說就是那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重複代碼,降低模塊之間的耦合度,並有利於未來的可操作性和可維護性。

    AOP 底層:動態代理。

    如果是接口採用 JDK 動態代理,如果是類採用 CGLIB 方式實現動態代理。

    AOP 的一些場景應用;

    AOP 用來封裝橫切關注點,具體可以在下面的場景中使用:

    Authentication 權限

    Caching 緩存

    Context passing 內容傳遞

    Error handling 錯誤處理

    Lazy loading 懶加載

    Debugging調試

    logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準

    Performance optimization 性能優化

    Persistence持久化

    Resource pooling 資源池

    Synchronization 同步

    Transactions 事務

    spring 注入的幾種方式
    (1)構造方法注入

    (2)setter 注入

    (3)基於註解

    Spring 中 Bean 的作用域有哪些

    作用域:用於確定 spring 創建 bean 實例個數

    取值(常用的兩個):

    singleton 單例,默認值。prototype 多例,一個 bean 的定義可以有多個實例。每執行一次 getBean 將獲得一個實例。

    請介紹一下 bean 的生命周期

    (1)bean 定義:在配置文件裏面用來進行定義。

    (2)bean 初始化:有兩種方式初始化:在配置文件中通過指定 init-method 屬性來完成實現
    org.springframwork.beans.factory.InitializingBean 接口

    (3)bean 調用:有三種方式可以得到 bean 實例,並進行調用

    (4)bean 銷毀:銷毀有兩種方式使用配置文件指定的 destroy-method 屬性實現
    org.springframwork.bean.factory.DisposeableBean 接口

    Spring 中自動裝配的方式有哪些

    no:不進行自動裝配,手動設置 Bean 的依賴關係。

    byName:根據 Bean 的名字進行自動裝配。

    byType:根據 Bean 的類型進行自動裝配。

    constructor:類似於 byType,不過是應用於構造器的參數,如果正好有一個 Bean與構造器的參數類型相同則可以自動裝配,否則會導致錯誤。autodetect:如果有默認的構造器,則通過 constructor 的方式進行自動裝配,否則使用 byType 的方式進行自動裝配。

    (自動裝配沒有自定義裝配方式那麼精確,而且不能自動裝配簡單屬性(基本類型、字符串等),在使用時應注意。)

    @Resource 和 @Autowired 區別?分別用在什麼場景?

    (1)共同點:兩者都可以寫在字段和 setter 方法上。兩者如果都寫在字段上,那麼就不需要再寫 setter 方法。

    (2)不同點:

    @Autowired

    @Autowired為Spring提供的註解,需要導入包
    org.springframework.beans.factory.annotation.Autowired;只按照 byType 注入。@Autowired 註解是按照類型(byType)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許 null 值,可以設置它的 required 屬性為 false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier 註解一起使用。

    @Resource

    @Resource 默 認 按 照 ByName 自 動 注 入 , 由 J2EE 提 供 , 需 要 導 入 包javax.annotation.Resource。@Resource 有兩個重要的屬性:name 和 type,而 Spring將@Resource 註解的 name 屬性解析為 bean 的名字,而 type 屬性則解析為 bean的類型。所以,如果使用 name 屬性,則使用 byName 的自動注入策略,而使用type 屬性時則使用 byType 自動注入策略。如果既不制定 name 也不制定 type 屬性,這時將通過反射機制使用 byName 自動注入策略。

    Hibernate 和 mybatis 的區別?

    (1)兩者最大的區別

    針對簡單邏輯,Hibernate 與 MyBatis 都有相應的代碼生成工具,可以生成簡單基本的 DAO 層方法。

    針對高級查詢,MyBatis 需要手動編寫 SQL 語句,以及 ResultMap,而 Hibernate有良好的映射機制,開發者無需關心 SQL 的生成與結果映射,可以更專註於流程。

    (2)開發難度對比

    Hibernate 的開發難度大於 MyBatis,主要由於 Hibernate 比較複雜,龐大,學習周期比較長。

    MyBatis 則相對簡單,並且 MyBatis 主要依賴於生氣了的書寫,讓開發者剛進更熟悉。

    (3)sql 書寫比較

    Hibernate 也可以自己寫 sql 來指定需要查詢的字段,但這樣就破壞了Hibernate 開發的簡潔性,不過 Hibernate 具有自己的日誌統計。

    MyBatis 的 sql 是手動編寫的,所以可以按照要求指定查詢的字段,不過沒有自己的日誌統計,所以要藉助 Log4j 來記錄日誌。

    (4)數據庫擴展性計較Hibernate 與數據庫具體的關聯在 XML 中,所以 HQL 對具體是用什麼數據庫
    並不是很關心MyBatis 由於所有 sql 都是依賴數據庫書寫的,所以擴展性、遷移性比較差。

    (5)緩存機制比較

    Hibernate 的二級緩存配置在 SessionFactory 生成配置文件中進行詳細配置,然後再在具體的表對象映射中配置那種緩存。

    MyBatis 的二級緩存配置都是在每個具體的表對象映射中進行詳細配置,這樣針對不同的表可以自定義不同的緩衝機制,並且 MyBatis 可以在命名空間中共享相同的緩存配置和實例,通過 Cache-ref 來實現。

    兩者比較,因為 Hibernate 對查詢對象有着良好的管理機制,用戶無需關心 SQL,所以在使用二級緩存時如果出現臟數據,系統會報出錯誤提示。 而 MyBatis 在這一方面使用二級緩存時需要特別小心,如果不能完全去頂數據更新操作的波及範圍,避免 cache 的盲目使用,否則,臟數據的出現會給系統的正常運行帶來很大的隱患。

    mybatis 是如何工作的?

    一、Mybatis 工作原理圖

    mybatis 原理圖如下所示:

    二、工作原理解析

    mybatis 應用程序通過 SqlSessionFactoryBuilder 從 mybatis-config.xml 配置文件(也可以用 Java 文件配置的方式,需要添加@Configuration)來構建 SqlSessionFactory(SqlSessionFactory 是線程安全的);

    然後,SqlSessionFactory 的實例直接開啟一個 SqlSession,再通過 SqlSession 實例獲得 Mapper 對象並運行 Mapper 映射的 SQL 語句,完成對數據庫的 CRUD 和事務提交,之後關閉 SqlSession。說明:SqlSession 是單線程對象,因為它是非線程安全的,是持久化操作的獨享對象,類似 jdbc 中的 Connection,底層就封裝了 jdbc 連接。

    詳細流程如下:

    (1)、加載 mybatis 全局配置文件(數據源、mapper 映射文件等),解析配置文件,MyBatis 基於 XML 配置文件生成 Configuration,和一個個 MappedStatement(包括了參數映射配置、動態 SQL 語句、結果映射配置),其對應着標籤項。

    (2)、SqlSessionFactoryBuilder 通過 Configuration 對象生成 SqlSessionFactory,用來開啟 SqlSession。

    (3)、SqlSession 對象完成和數據庫的交互:

    a、用戶程序調用 mybatis 接口層 api(即 Mapper 接口中的方法)

    b、SqlSession 通過調用 api 的 Statement ID 找到對應的 MappedStatement 對象

    c、通過 Executor(負責動態 SQL 的生成和查詢緩存的維護)將 MappedStatement對象進行解析,sql 參數轉化、動態 sql 拼接,生成 jdbc Statement 對象

    d、JDBC 執行 sql。

    e、藉助 MappedStatement 中的結果映射關係,將返回結果轉化成 HashMap、JavaBean 等存儲結構並返回。

    Hibernate 對象有幾個狀態值?

    Transient 瞬時 :對象剛 new 出來,還沒設 id,設了其他值。

    Persistent 持久:調用了 save()、saveOrUpdate(),就變成 Persistent,有 id

    Detached 脫管 : 當 session close()完之後,變成 Detached。

    簡述 Springmvc 的流程;

    spring 工作的流程

    流程如下:(1)用戶發起請求到前端控制器(DispatcherServlet),該控制器會過濾出哪些請求可以訪問 Servlet、哪些不能訪問。就是 url-pattern 的作用,並且會加載springmvc.xml 配置文件。

    (2)前端控制器會找到處理器映射器(HandlerMapping),通過 HandlerMapping完成 url 到 controller 映射的組件,簡單來說,就是將在 springmvc.xml 中配置的或者註解的 url 與對應的處理類找到並進行存儲,用 map<url,handler>這樣的方式來存儲。

    (3)HandlerMapping 有了映射關係,並且找到 url 對應的處理器,HandlerMapping就會將其處理器(Handler)返回,在返回前,會加上很多攔截器。

    (4)DispatcherServlet 拿到 Handler 后,找到 HandlerAdapter(處理器適配器),通過它來訪問處理器,並執行處理器。

    (5)執行處理器

    (6)處理器會返回一個 ModelAndView 對象給 HandlerAdapter

    (7) 通 過 HandlerAdapter 將 ModelAndView 對 象 返 回 給 前 端 控 制 器(DispatcherServlet)

    (8)前端控制器請求視圖解析器(ViewResolver)去進行視圖解析,根據邏輯視圖名解析成真正的視圖(jsp),其實就是將 ModelAndView 對象中存放視圖的名稱進行查找,找到對應的頁面形成視圖對象

    (9)返回視圖對象到前端控制器。

    (10)視圖渲染,就是將 ModelAndView 對象中的數據放到 request 域中,用來讓頁面加載數據的。

    (11)通過第 8 步,通過名稱找到了對應的頁面,通過第 10 步,request 域中有了所需要的數據,那麼就能夠進行視圖渲染了。最後將其返回即可。

    Springmvc 和 Springboot 有什麼區別?

    Spring MVC 是基於 Spring 的一個 MVC 框架 ;

    Spring Boot 是基於 Spring4 的條件註冊的一套快速開發整合包。

    Springboot 為什麼配置簡單?(即它自動做了什麼操作才能簡化程序員的操作)
    主要是使用了 spring3 之後提供的註解,來代替 xml 文件的配置,最核心的是以下兩個註解

    @Configuration,標註在類上,相當於定義一個配置類,一份 spring 的配置文件

    @Bean,類似於 spring 配置文件中的通過這兩個註解就可以用 java 代碼的方式來完成相關 spring 配置

    持久層設計要考慮的問題有哪些?請談一下你用過的持久層框架都有哪些?

    “持久”就是將數據保存到可掉電式存儲設備中以便今後使用,簡單的說,就是將內存中的數據保存到關係型數據庫、文件系統、消息隊列等提供持久化支持的設備中。持久層就是系統中專註於實現數據持久化的相對獨立的層面。

    持久層設計的目標包括:

    數據存儲邏輯的分離,提供抽象化的數據訪問接口。

    數據訪問底層實現的分離,可以在不修改代碼的情況下切換底層實現。

    資源管理和調度的分離,在數據訪問層實現統一的資源調度(如緩存機制)。

    數據抽象,提供更面向對象的數據操作。

    持久層框架有: Hibernate、MyBatis、TopLink、 Guzz、 jOOQ、 Spring Data、ActiveJDBC

    需要更多技術文檔可以在後台私信【學習】

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※超省錢租車方案

    ※教你寫出一流的銷售文案?

    網頁設計最專業,超強功能平台可客製化

  • 005.OpenShift訪問控制-權限-角色

    005.OpenShift訪問控制-權限-角色

    一 Kubetcl namespace

    1.1 namespace描述


    Kubernetes namespace提供了將一組相關資源組合在一起的機制。在Red Hat OpenShift容器平台中,project是一個帶有附加註釋的Kubernetes namespace。

    namespace提供以下特性:

    1. 命名資源,以避免基本的命名衝突;
    2. 將管理權限授予受信任的用戶;
    3. 限制用戶資源消耗的能力;
    4. 用戶和用戶組隔離。

    1.2 project


    project提供了一種機制,通過這種機制可以管理普通用戶對資源的訪問。project允許一組用戶獨立於其他組組織和管理其內容,必須允許用戶訪問項目。如果允許創建項目,用戶將自動訪問自己的項目。

    項目可以有單獨的name、display name和description。

    name是項目的唯一標識符,在使用CLI工具或API時都是基於name,name的最大長度為63個字符。

    display name是項目在web控制台中显示的方式(默認為name)。

    description是項目的更詳細描述,並且在web控制台中也可見。

    以下組件適用於項目:

    • Object:pod、service、rc等;
    • Policies:決定用戶可以或不能對對象執行哪些操作的規則;
    • Constraints:可以限制的每種對象的配額。

    1.3 cluster管理


    集群管理員可以創建項目並將項目的管理權限委託給任何用戶。在OpenShift容器平台中,項目用於對相關對象進行分組和隔離。

    管理員可以讓用戶訪問某些項目,允許他們創建自己的項目,並在單個項目中賦予他們管理權限。

    管理員可以將角色應用於允許或限制其創建項目能力的用戶和組,同時可以在用戶初始登錄之前分配角色。

    限制項目創建:從通過身份驗證的用戶和組中刪除self-provisioning集群角色,將拒絕任何新項目的權限。

    [root@master ~]$ oc adm policy remove-cluster-role-from-group \

    self-provisioner \

    system:authenticated \

    system:authenticated:oauth

    授予項目創建:項目創建授予具有self-供應者角色和self-provisione集群角色綁定的用戶。默認情況下,所有經過身份驗證的用戶都可以使用這些角色。

    [root@master ~]$ oc adm policy add-cluster-role-to-group \

    self-provisioner \

    system:authenticated \

    system:authenticated:oauth

    1.4 創建project


    如果項目創建權限被授予用戶,則可以使用oc命令創建project。

    [root@master ~]$ oc new-project demoproject \

    –description=”Demonstrate project creation” \

    –display-name=”demo_project”

    二 OpenShift角色

    2.1 角色概述


    role具有不同級別的訪問和策略,包括集群和本地策略。user和group可以同時與多個role關聯。運行oc description命令查看角色及其綁定的詳細信息。

    在集群策略中具有cluster-admin缺省角色的用戶可以查看集群策略和所有本地策略。在給定的本地策略中具有admin缺省角色的用戶可以基於per-project查看策略。

    可通過以下命令查看當前的集群綁定集,其中显示綁定到不同角色的用戶和組。

    [root@demo ~]# oc describe clusterPolicyBindings :default

    2.2 查看本地policy


    儘管本地角色列表及其關聯的規則集在本地策略中是不可查看的,但是所有缺省角色仍然適用,並且可以添加到用戶或組中,cluster-admin缺省角色除外。但是,本地綁定是可見的。

    可通過以下命令查看當前的本地綁定,其中显示綁定到不同角色的用戶和組。

    [root@demo ~]# oc describe policyBindings :default

    提示:默認情況下,在本地策略中,只會列出admin角色的綁定。但是,如果將其他默認角色添加到本地策略中的用戶和組,也會列出它們。

    2.3 管理role綁定


    向用戶或組添加或綁定角色,從而實現向用戶或組提供角色授予的相關訪問權限。可以使用oc adm policy命令在用戶和組之間添加和刪除角色。

    當使用以下操作管理本地策略的用戶和組角色時,可以使用-n選項指定項目。如果沒有指定,則使用當前項目。

    常見管理本地策略操作:





























    命令 描述
    oc adm policy who-can verb resource 設置哪些用戶可以對資源執行操作
    oc adm policy add-role-to-user role username 將指定角色綁定到指定用戶
    oc adm policy remove-role-from-user role username 從指定用戶中移除給定角色
    oc adm policy remove-user username 刪除指定的用戶及其所有角色
    oc adm policy add-role-to-group role groupname 將指定的角色綁定到指定的組
    oc adm policy remove-role-fromgroup role groupname 從指定組中移除給定角色
    oc adm policy remove-group groupname 刪除指定的組及其所有角色


    還可以使用如下所示的的操作管理cluster policy的role binding,這類命令不需要-n選項,因為cluster policy不在namespace級別上操作。

    常見管理cluster policy操作:




















    命令 描述
    oc adm policy add-cluster-role-to-user role username 將集群中所有項目的指定角色綁定到指定用戶
    oc adm policy remove-cluster-role-from-user role username 為集群中的所有項目從指定用戶中刪除指定角色
    oc adm policy add-cluster-role-togroup role groupname 為集群中的所有項目將指定的角色綁定到指定的組
    oc adm policy remove-cluster-role-from-group role groupname 從集群中所有項目的指定組中移除給定角色


    提示:oc policy命令應用於當前項目,而oc adm policy命令應用於集群範圍的操作。

    示例:在example項目中為developer用戶提供admin角色。

    [root@demo ~]# oc adm policy add-role-to-user admin developer -n example

    [root@demo ~]# oc describe policybindings :default -n example #檢查綁定

    三 安全上下文約束(SCCS)

    3.1 SCCS概述


    OpenShift提供安全上下文約束(SCCS),它控制pod可以執行的操作和它可以訪問的資源。默認情況下,任何容器的執行都只授予受限制的SCC定義的功能。

    SCCS相關命令:

      1 [user@demo ~]$ oc get scc			                        #列出可用的SCC
      2 [user@demo ~]$ oc describe scc scc_name		                #現實特定SCC詳細信息
      3 [user@demo ~]$ oc adm policy add-scc-to-user scc_name user_name
      4 [user@demo ~]$ oc adm policy add-scc-to-group scc_name group_name	#要授予用戶或組特定的SCC
      5 [user@demo ~]$ oc adm policy remove-scc-from-user scc_name user_name
      6 [user@demo ~]$ oc adm policy remove-scc-from-group scc_name group_name	#從特定的SCC中刪除用戶或組


    四 服務賬戶

    4.1 服務賬戶


    service account提供了一種靈活的方法來控制API訪問,而無需共享常規用戶的憑據。如果應用程序需要訪問受限制的SCC未授予的功能,可創建一個新的、特定的service account並將其添加到適當的SCC中。

    例如,在缺省情況下,OpenShift不支持部署需要提升特權的應用程序。若有此需求,可創建一個service account,修改dc,然後添加service account至SCC。

    示例:將anyuid配置為在容器中作為root用戶運行。

    [user@demo ~]$ oc create serviceaccount useroot #創建一個名為useroot的新服務帳戶

    [user@demo ~]$ oc patch dc/demo-app \

    –patch ‘{“spec”:{“template”:{“spec”:{“serviceAccountName”: “useroot”}}}}’ #修改應用程序的DC

    [user@demo ~]$ oc adm policy add-scc-to-user anyuid -z useroot #將useroot服務帳戶添加到anyuid SCC中,作為容器中的根用戶運行

    4.2 Web管理user成員


    OCP平台的默認配置是,在用戶首次登錄成功時,自動創建該用戶對象。

    要管理允許訪問項目的用戶,請以項目管理員或集群管理員的身份登錄到web控制台,並選擇要管理的項目。在左側窗格中,單擊Resources——>membership進入項目member頁面。

    在Users列中,在突出显示的文本框中輸入用戶名。在“添加另一個角色”列中,從用戶所在行的列表中選擇一個角色,然後單擊“添加”。

    4.3 Cli管理user成員


    CLI中如果自動創建對象功能被關閉,集群管理員可通過如下方式創建新用戶:

    [root@master ~]$ oc create user demo-user

    同時還需要在身份認證軟件中創建用戶,如為HTPasswdIdentityProvider才用戶命令如下:

    [root@master ~]$ htpasswd /etc/origin/openshift-passwd demo-user

    要向用戶添加項目角色,首先使用oc project命令輸入項目,然後使用oc policy add-role-to-user命令:

    [root@master ~]$ oc policy add-role-to-user edit demo-user

    要從用戶中刪除項目角色,使用oc policy remove-role-from-user命令:

    [root@master ~]$ oc policy remove-role-from-user edit demo-user

    並不是所有OpenShift角色都由項目限定範圍。要分配這些規則,請使用oc adm policy command命令。

    [root@master ~]$ oc adm policy add-cluster-role-to-user cluster-admin admin

    4.4 身份驗證和授權


    身份驗證層標識與對OpenShift容器平台API的請求相關聯的用戶,然後授權層使用關於請求用戶的身份信息來確定是否應該允許該請求。

    • user和group


    OCP容器平台中的用戶是一個可以向OpenShift API發出請求的實體。通常,這表示與OpenShift交互的develop或administrator的帳戶。

    可以將用戶分配給一個或多個組,每個組表示一組特定的角色(或權限)。當需要通過管理授權策略給多個客戶授權時候,group會比較合適。例如允許訪問項目中的對象,而不是單獨授予用戶。

    • Authentication Tokens


    API調用必須使用訪問令牌或X.509證書進行身份驗證,會話token表示用戶,並且是短期的,默認情況下在24小時內到期。

    可以通過運行oc whoami命令來驗證經過身份驗證的用戶。

    [root@master ~]$ oc login -u demo-user

    [root@master ~]$ oc whoami

    demo-user

    4.5 身份驗證類型


    本環境中,身份驗證由HTPasswdIdentityProvider模塊提供,該模塊根據使用htpasswd命令生成的文件驗證用戶名和密碼。

    OpenShift容器平台支持的其他認證類型包括:

    • Basic Authentication (Remote)


    一種通用的後端集成機制,允許用戶使用針對遠程標識提供者驗證的憑據登錄到OpenShift容器平台。用戶將他們的用戶名和密碼發送到OpenShift容器平台,OpenShift平台通過到服務器的請求驗證這些憑據,並將憑據作為基本的Auth頭傳遞。這要求用戶在登錄過程中向OpenShift容器平台輸入他們的憑據。

    • Request Header Authentication


    用戶使用請求頭值(如X-RemoteUser)登錄到OpenShift容器平台。它通常與身份驗證代理結合使用,身份驗證代理對用戶進行身份驗證,然後通過請求頭值為OpenShift容器平台提供用戶標識。

    • Keystone Authentication


    Keystone是一個OpenStack項目,提供標識、令牌、目錄和策略服務。OpenShift容器平台與Keystone集成,通過配置OpenStack Keystone v3服務器將用戶存儲在內部數據庫中,從而支持共享身份驗證。這種配置允許用戶使用Keystone憑證登錄OpenShift容器平台。

    • LDAP Authentication


    用戶使用他們的LDAP憑證登錄到OpenShift容器平台。在身份驗證期間,LDAP目錄將搜索與提供的用戶名匹配的條目。如果找到匹配項,則嘗試使用條目的專有名稱(DN)和提供的密碼進行簡單綁定。

    • GitHub Authentication


    GitHub使用OAuth,它允許與OpenShift容器平台集成使用OAuth身份驗證來促進令牌交換流。這允許用戶使用他們的GitHub憑證登錄到OpenShift容器平台。為了防止使用GitHub用戶id的未授權用戶登錄到OpenShift容器平台集群,可以將訪問權限限制在特定的GitHub組織中。

    五 管理項目及賬戶

    5.1 前置準備


    準備完整的OpenShift集群,參考《003.OpenShift網絡》2.1。

    5.2 本練習準備


    [student@workstation ~]$ lab secure-resources setup

    5.3 創建htpasswd賬戶

      1 [kiosk@foundation0 ~]$ ssh root@master
      2 [root@master ~]# htpasswd -b /etc/origin/master/htpasswd user1 redhat
      3 [root@master ~]# htpasswd -b /etc/origin/master/htpasswd user2 redhat
      4 #添加基於htpasswd形式的user1和user2,密碼都為redhat。


    5.4 設置策略

      1 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com	#使用管理員登錄
      2 [student@workstation ~]$ oc adm policy remove-cluster-role-from-group \
      3 self-provisioner system:authenticated:oauth
      4 #刪除所有賦予普通創建項目的功能,該命令可參考本環境如下目錄中的命令。
      5 [student@workstation ~]$ cat /home/student/DO280/labs/secure-resources/configure-policy.sh
      6 #!/bin/bash
      7 oc adm policy remove-cluster-role-from-group \
      8     self-provisioner system:authenticated system:authenticated:oauth


    5.5 驗證策略

      1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com	#使用普通用戶user1登錄
      2 [student@workstation ~]$ oc new-project test					#測試創建project
      3 Error from server (Forbidden): You may not request a new project via this API.


    5.6 創建項目

      1 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com	#使用集群管理員登錄
      2 [student@workstation ~]$ oc new-project project-user1				#創建兩個項目
      3 [student@workstation ~]$ oc new-project project-user2


    5.7 將項目與user關聯

      1 #選擇項目1
      2 Now using project "project-user1" on server "https://master.lab.example.com:443".
      3 [student@workstation ~]$ oc policy add-role-to-user admin user1		#將user1添加為項目1的管理員
      4 role "admin" added: "user1"
      5 [student@workstation ~]$ oc policy add-role-to-user edit user2		#將user2添加為項目1的開發員
      6 role "edit" added: "user2"
      7 
      8 [student@workstation ~]$ oc project project-user2			        #選擇項目2
      9 Now using project "project-user2" on server "https://master.lab.example.com:443".
     10 [student@workstation ~]$ oc policy add-role-to-user edit user2		#將user2添加為項目2的開發員
     11 role "edit" added: "user2"


    5.8 驗證訪問

      1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com	#使用user1登錄
      2 [student@workstation ~]$ oc project project-user1					#驗證項目1的訪問
      3 Already on project "project-user1" on server "https://master.lab.example.com:443".
      4 [student@workstation ~]$ oc project project-user2					#驗證項目2的訪問
      5 error: You are not a member of project "project-user2".
      6 You have one project on this server: project-user1
      7 
      8 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com	#使用user2登錄
      9 [student@workstation ~]$ oc project project-user1
     10 Already on project "project-user1" on server "https://master.lab.example.com:443".	#驗證項目1的訪問
     11 [student@workstation ~]$ oc project project-user2
     12 Now using project "project-user2" on server "https://master.lab.example.com:443".	#驗證項目2的訪問


    5.9 部署特權應用

      1 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com
      2 [student@workstation ~]$ oc project project-user1
      3 Now using project "project-user1" on server "https://master.lab.example.com:443".
      4 [student@workstation ~]$ oc new-app --name=nginx --docker-image=registry.lab.example.com/nginx:latest
      5 #使用在項目1上不具備admin權限的用戶user2登錄,並部署應用,會出現如下提示:





    5.10 驗證部署

      1 [student@workstation ~]$ oc get pods




    結論:由上可知,部署失敗是因為容器映像需要root用戶,pod以CrashLoopBackOff或錯誤狀態結束。

    5.11 故障排除


    若要解決此故障需要減少特定項目的安全限制。

    要使用特權訪問運行容器,可創建一個允許pod使用操作系統普通用戶運行的service account。

    如下部分需要具有項目管理員特權的用戶執行,而另一些操作需要具有集群管理員特權的用戶執行。

    本環境中,相關操作命令可以從/home/student/DO280/labs/secure-resources文件夾中的configure-sc.sh腳本運行或複製。

      1 [student@workstation ~]$ oc login -u user1 -p redhat https://master.lab.example.com	#使用項目1的admin賬戶登錄 
      2 [student@workstation ~]$ oc create serviceaccount useroot		  #創建服務賬戶
      3 serviceaccount "useroot" created
      4 [student@workstation ~]$ oc login -u admin -p redhat https://master.lab.example.com	#使用集群管理員登錄
      5 [student@workstation ~]$ oc project project-user1			  #選擇項目1
      6 Already on project "project-user1" on server "https://master.lab.example.com:443".
      7 [student@workstation ~]$ oc adm policy add-scc-to-user anyuid -z useroot  #設置SCC策略
      8 scc "anyuid" added to: ["system:serviceaccount:project-user1:useroot"]    #將服務帳戶與anyuid安全上下文關聯,此操作需要集群管理員用戶。
      9 [student@workstation ~]$ oc login -u user2 -p redhat https://master.lab.example.com	#切換user2用戶
     10 [student@workstation ~]$ oc project project-user1
     11 Already on project "project-user1" on server "https://master.lab.example.com:443".
     12 [student@workstation ~]$ oc patch dc nginx --patch='{"spec":{"template":{"spec":{"serviceAccountName": "useroot"}}}}'



    #更新負責管理nginx的dc資源,任何開發人員用戶都可以執行此操作。本環境中,相關操作命令可以從/home/student/DO280/labs/secure-resources文件夾中的configure-sc.sh腳本運行或複製。

    5.12 驗證確認

      1 [student@workstation ~]$ oc get pods
      2 NAME            READY     STATUS    RESTARTS   AGE
      3 nginx-2-98k8f   1/1       Running   0          3m
      4 

    5.13 暴露服務

      1 [student@workstation ~]$ oc expose svc nginx
      2 route "nginx" exposed
      3 [student@workstation ~]$ oc get svc
      4 NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
      5 nginx     ClusterIP   172.30.118.63   <none>        80/TCP    13m
      6 [student@workstation ~]$ oc get route
      7 NAME      HOST/PORT                                  PATH      SERVICES   PORT      TERMINATION   WILDCARD
      8 nginx     nginx-project-user1.apps.lab.example.com             nginx      80-tcp                  None


    5.14 測試訪問

      1 [student@workstation ~]$ curl -s http://nginx-project-user1.apps.lab.example.com

    5.15 策略刪除演示

      1 [student@workstation ~]$ oc login -u admin -p redhat
      2 [student@workstation ~]$ oc adm policy add-cluster-role-to-group self-provisioner system:authenticated system:authenticated:oauth
      3 cluster role "self-provisioner" added: ["system:authenticated" "system:authenticated:oauth"]
      4 [student@workstation ~]$ oc delete project project-user1
      5 project "project-user1" deleted
      6 [student@workstation ~]$ oc delete project project-user2
      7 [root@master ~]# htpasswd -D /etc/origin/master/htpasswd user1 
      8 [root@master ~]# htpasswd -D /etc/origin/master/htpasswd user2


    #為所有常規用戶重新啟用項目創建,即重置為初始狀態。本環境中,相關操作命令可以從/home/student/DO280/labs/secure-resources文件夾中的restore-policy.sh腳本運行或複製。

    六 管理加密信息

    6.1 secret特性


    Secret對象類型提供了一種機制來保存敏感信息,如密碼、OCP客戶端配置文件、Docker配置文件和私有倉庫憑據。Secrets將敏感內容與Pod解耦。可以使用Volume插件將Secrets掛載到容器上,或者系統可以使用Secrets代表pod執行操作。

    Secrets的主要特徵包括:

    • Secrets data可以獨立於其定義引用。
    • Secrets data Volume由臨時文件存儲支持。
    • 可以在名稱空間中共享Secrets data。

    6.2 創建Secrets


    在依賴於該Secrets的pod之前創建一個Secrets。

      1 [user@demo ~]$ oc create secret generic secret_name \
      2 --from-literal=key1=secret1 \
      3 --from-literal=key2=secret2	#用secret data創建secret對象
      4 [user@demo ~]$ oc secrets add --for=mount serviceaccount/serviceaccount-name \
      5 secret/secret_name		#更新pod的服務帳戶,允許引用該secrets。

    例如,允許一個運行在指定服務帳戶下的pod掛載一個secrets

    創建一個pod,該pod使用環境變量或數據卷作為文件的方式使用該secret,通常使用模板完成。

    6.3 使用secret暴露Pod


    secrets可以作為數據卷掛載,也可以作為環境變量以便供pod中的容器使用。

    例如,要向pod公開一個secrets,首先創建一個secrets並將username和password以k/v形式配置,然後將鍵名分配給pod的YAML文件env定義。

    示例:創建名為demo-secret的secrets,它定義用戶名和密碼為username/demo-user。

    [user@demo ~]$ oc create secret generic demo-secret \

    –from-literal=username=demo-user

    要使用前面的secret作為MySQL數據庫pod的數據庫管理員密碼,請定義環境變量,並引用secret名稱和密碼。

      1 env:
      2   - name: MYSQL_ROOT_PASSWORD
      3     valueFrom:
      4       secretKeyRef:
      5        key: username
      6        name: demo-secret


    6.4 web端管理secret


    從web控制台管理secret:

    1. 以授權用戶身份登錄到web控制台。

    2. 創建或選擇一個項目來承載secret。

    3. 導航到resource——>secrets。

    6.5 Secret使用場景


    • password和user names


    敏感信息(如password和user name)可以存儲在一個secret中,該secret被掛載為容器中的數據卷。數據显示為位於容器的數據卷目錄中的文件中的內容。然後,應用程序(如數據庫)可以使用這些secret對用戶進行身份驗證。

    • 傳輸層安全性(TLS)和密鑰對


    通過讓集群將簽名證書和密鑰對生成到項目名稱空間中的secret中,可以實現對服務的通信的保護。證書和密鑰對使用PEM格式存儲以類似tls.crt和tls.key的格式存儲在secret的pod中。

    七 ConfigMap對象

    7.1 ConfigMap概述


    ConfigMaps對象類似於secret,但其設計目的是支持處理不包含敏感信息的字符串。ConfigMap對象持有配置數據的鍵值對,這些配置數據可以在pods中使用,或者用於存儲系統組件(如控制器)的配置數據。

    ConfigMap對象提供了將配置數據注入容器的機制。ConfigMap存儲精細的粒度信息,比如單個屬性,或者詳細信息,比如整個配置文件或JSON blob。

    7.2 CLI創建ConfigMap


    可以使用–from-literal選項從CLI創建ConfigMap對象。

    示例:創建一個ConfigMap對象,該對象將IP地址172.20.30.40分配給名為serverAddress的ConfigMap密鑰。

      1 [user@demo ~]$ oc create configmap special-config \
      2 --from-literal=serverAddress=172.20.30.40
      3 [user@demo ~]$ oc get configmaps special-config -o yaml		#查看configMap
      4 apiVersion: v1
      5 data:
      6   key1: serverAddress=172.20.30.40
      7 kind: ConfigMap
      8 metadata:
      9   creationTimestamp: 2017-07-10T17:13:31Z
     10   name: special-config
     11 ……
     12 在配置映射的pod定義中填充環境變量APISERVER。
     13 env:
     14   - name: APISERVER
     15       valueFrom:
     16         configMapKeyRef:
     17           name: special-config
     18           key: serverAddress


    7.3 web管理ConfigMap


    從web控制台管理ConfigMap對象:

    1. 以授權用戶身份登錄到web控制台。

    2. 創建或選擇一個項目來承載ConfigMap。

    3. 導航到資源→配置映射。

    八 加密練習

    8.1 前置準備


    準備完整的OpenShift集群,參考《003.OpenShift網絡》2.1。

    8.2 本練習準備


    [student@workstation ~]$ lab secure-secrets setup

    8.3 創建項目

      1 [student@workstation ~]$ oc login -u developer -p redhat
      2 [student@workstation ~]$ cd /home/student/DO280/labs/secure-secrets/
      3 [student@workstation secure-secrets]$ less mysql-ephemeral.yml		#導入本環境MySQL模板







    模板解讀:

    該mysql-ephemeral.yml模板文件,包含openshift項目中的mysql臨時模板,pod所需的其他環境變量由模板參數初始化,並具有默認值。

    但沒有secret定義,後續操作將手動創建模板所需的secret。

    根據模板的要求,創建一個包含MySQL容器image使用的憑證的secret,將這個secret命名為mysql。

    • 應用程序訪問的數據庫用戶名由database-user定義。
    • 數據庫用戶的密碼由database-password定義。
    • 數據庫管理員密碼由database-root-password定義

    8.4 創建新secret

      1 [student@workstation secure-secrets]$ oc create secret generic mysql \
      2 --from-literal='database-user'='mysql' \
      3 --from-literal='database-password'='redhat' \
      4 --from-literal='database-root-password'='do280-admin'
      5 [student@workstation secure-secrets]$ oc get secret mysql -o yaml	#確認secret




    8.5 創建應用

      1 [student@workstation secure-secrets]$ oc new-app --file=mysql-ephemeral.yml
      2 [student@workstation secure-secrets]$ oc get pods		#確認應用
      3 NAME            READY     STATUS    RESTARTS   AGE
      4 mysql-1-j4fnz   1/1       Running   0          1m


    8.6 端口轉發

      1 [student@workstation secure-secrets]$ cd
      2 [student@workstation ~]$ oc port-forward mysql-1-j4fnz 3306:3306



    提示:驗證完成之前forward不要關閉。

    8.7 確認驗證

      1 [student@workstation ~]$ mysql -uroot -pdo280-admin -h127.0.0.1	#新開終端測試MySQL



    九 管理security policy

    9.1 OCP authorization授權


    OCP定義了用戶可以執行的兩組主要操作:

    與項目相關的操作(也稱為本地策略):project-related

    與管理相關的操作(也稱為集群策略):administration-related

    由於這兩種策略都有大量可用的操作,所以將一些操作分組並定義為角色。














    默認角色 描述
    cluster-admin 此角色中的所有用戶都可以管理OpenShift集群。
    cluster-status 此角色中的所有用戶都提供對集群信息的只讀訪問。


    為管理本地政策,OCP提供以下角色:




















    默認角色 描述
    edit 角色中的用戶可以從項目中創建、更改和刪除公共應用程序資源,比如service和dc。 但是不能對限制範圍和配額等管理資源採取行動,也不能管理對項目的訪問權限。
    basic-user 角色中的用戶具有對項目的讀訪問權。
    self-provisioner 角色中的用戶可以創建新項目。這是一個集群角色,而不是項目角色。
    admin 角色中的用戶可以管理項目中的所有資源,包括授予對項目的其他用戶的訪問權


    除了能夠創建新應用程序之外,admin角色還允許用戶訪問項目資源,比如配額和限制範圍。

    edit角色允許用戶在項目中充當開發人員,但要在項目管理員配置的約束下工作。

    9.2 相關命令

      1 向集群用戶添加角色
      2 $ oc adm policy add-cluster-role-to-user cluster-role username
      3 示例:將普通用戶更改為集群管理員。
      4 $ oc adm policy add-cluster-role-to-user cluster-role username
      5 從用戶中刪除集群角色
      6 $ oc adm policy remove-cluster-role-from-user cluster-role username
      7 示例:將集群管理員更改為普通用戶。
      8 $ oc adm policy remove-cluster-role-from-user cluster-admin username
      9 將指定的用戶綁定到項目中的角色
     10 $ oc adm policy add-role-to-user role-name username -n project
     11 示例:在WordPress項目中dev用戶綁定basic-user角色。
     12 $ oc adm policy add-role-to-user basic-user dev -n wordpress


    9.3 權限及規則


    OpenShift將一組規則集合成一個角色,規則由謂詞和資源定義。如create user是OpenShift中的一條規則,它是一個名為cluster-admin的角色的所擁有的權限的一部分。

      1 $ oc adm policy who-can delete user

    9.4 user類型


    與OCP的交互基於用戶,OCP的user對象表示可以通過向該用戶或用戶組添加角色來從而實現相應權限的授予。

    Regular users:通常以這種用戶類型與OCP交互,常規用戶用User對象表。例如,user1,user2。

    System users:通常在安裝OCP中定義基礎設施時自動創建的,主要目的是使基礎設施能夠安全地與API交互。包括集群管理員(可以訪問所有內容)、每個節點的用戶、路由器和內部倉庫使用的用戶,以及各種其他用戶。還存在一個匿名系統用戶,默認情況下,該用戶用於未經身份驗證的請求。system user主要包括:system:admin、system:openshift-registry和system:node:node1.example.com。

    Service accounts:這些是與項目關聯的特殊系統用戶。有些是在第一次創建項目時自動創建的,項目管理員可以創建多個,以便定義對每個項目內容的訪問。Service accounts由ServiceAccount對象表示。Service accounts主要包括:system:serviceaccount:default:deployer和system:serviceaccount:foo:builder。

    每個用戶在訪問OpenShift容器平台之前必須進行身份驗證。沒有身份驗證或身份驗證無效的API請求將使用匿名系統用戶身份驗證來請求服務。身份驗證成功后,策略確定用戶被授權做什麼。

    9.5 安全上下文約束(SCCS)


    OpenShift提供了一種名為安全上下文約束的安全機制,它限制對資源的訪問,但不限制OpenShift中的操作。

    SCC限制從OpenShift中運行的pod到主機環境的訪問:

    • 運行特權容器
    • 請求容器的額外功能
    • 使用主機目錄作為卷
    • 更改容器的SELinux上下文
    • 更改用戶ID


    社區開發的一些容器可能需要放鬆安全上下文約束,因為它們可能需要訪問默認禁止的資源,例如文件系統、套接字或訪問SELinux上下文。

    OpenShift定義的安全上下文約束(SCCs)可以使用以下命令作為集群管理員列出。

    $ oc get scc

    SCC通常有以下7中SCCS:

    • anyuid
    • hostaccess
    • hostmount-anyuid
    • nonroot
    • privileged
    • restricted(默認)


    $ oc describe scc anyuid #查看某一種SCC詳情

    OpenShift創建的所有容器都使用restricted類型的SCC,它提供了對OpenShift外部資源的有限訪問。

    對於anyuid安全上下文,run as user策略被定義為RunAsAny,表示pod可以作為容器中可用的任何用戶ID運行。這允許需要特定用戶使用特定用戶ID運行命令的容器。

    要將容器更改為使用不同的SCC運行,需要創建綁定到pod的服務帳戶。

    $ oc create serviceaccount service-account-name #首先創建服務賬戶

    $ oc adm policy add-scc-to-user SCC -z service-account #將服務帳戶與SCC關聯

    要確定哪個帳戶可以創建需要更高安全性要求的pod,可以使用scc-subject-review子命令。

    $ oc export pod pod-name > output.yaml

    $ oc adm policy scc-subject-review -f output.yaml

    9.6 OpenShift與SELinux


    OpenShift要求在每個主機上啟用SELinux,以便使用強制訪問控制提供對資源的安全訪問。同樣,由OpenShift管理的Docker容器需要管理SELinux上下文,以避免兼容性問題。

    為了最小化在不支持SELinux的情況下運行容器的風險,可以創建SELinux上下文策略。

    為了更新SELinux上下文,可以使用現有的SCC作為起點生成一個新的SCC。

    $ oc export scc restricted > custom_selinux.yml #導出默認的SCC

    編輯導出的YAML文件以更改SCC名稱和SELinux上下文。

    $ oc create -f yaml_file #使用修改后的ymal重新創建一個SCC

    9.7 特權容器


    有些容器可能需要訪問主機的運行時環境。S2I構建器容器需要訪問宿主docker守護進程來構建和運行容器。

    例如,S2I構建器容器是一類特權容器,它要求訪問超出其自身容器的限制。這些容器可能會帶來安全風險,因為它們可以使用OpenShift節點上的任何資源。通過創建具有特權訪問權的服務帳戶,可以使用SCCs啟用特權容器的訪問。

    十 資源訪問控制綜合實驗

    10.1 前置準備


    準備完整的OpenShift集群,參考《003.OpenShift網絡》2.1。

    10.2 本練習準備

      1 [student@workstation ~]$ lab secure-review setup

    10.3 創建用戶

      1 [root@master ~]# htpasswd /etc/origin/master/htpasswd user-review
      2 New password: 【redhat】
      3 Re-type new password: 【redhat】


    10.4 修改策略

      1 [student@workstation ~]$ oc login -u admin -p redhat
      2 [student@workstation ~]$ oc adm policy remove-cluster-role-from-group \
      3 self-provisioner system:authenticated system:authenticated:oauth
      4 禁用所有常規用戶的項目創建功能


    10.5 確認驗證

      1 [student@workstation ~]$ oc login -u user-review -p redhat
      2 [student@workstation ~]$ oc new-project test			#普通用戶無法創建項目
      3 Error from server (Forbidden): You may not request a new project via this API.


    10.6 創建項目

      1 [student@workstation ~]$ oc login -u admin -p redhat
      2 [student@workstation ~]$ oc new-project secure-review		#使用管理員創建項目


    10.7 授權用戶

      1 [student@workstation ~]$ oc project secure-review
      2 Already on project "secure-review" on server "https://master.lab.example.com:443".
      3 [student@workstation ~]$ oc policy add-role-to-user edit user-review	#將edit的role和user-review進行關聯


    10.8 測試訪問

      1 [student@workstation ~]$ oc login -u user-review -p redhat
      2 [student@workstation ~]$ oc project secure-review		#測試訪問
      3 Already on project "secure-review" on server "https://master.lab.example.com:443".


    10.9 檢查模板

      1 [student@workstation ~]$ cd /home/student/DO280/labs/secure-review/
      2 [student@workstation secure-review]$ less mysql-ephemeral.yml





    模板解讀:

    該mysql-ephemeral.yml模板文件,包含openshift項目中的mysql臨時模板,pod所需的其他環境變量由模板參數初始化,並具有默認值。

    但沒有secret定義,後續操作將手動創建模板所需的secret。

    根據模板的要求,創建一個包含MySQL容器image使用的憑證的secret,將這個secret命名為mysql。

    • 應用程序訪問的數據庫用戶名由database-user定義。
    • 數據庫用戶的密碼由database-password定義。
    • 數據庫管理員密碼由database-root-password定義


    使用user-review developer用戶創建一個名為mysql的secret。這個secret應該存儲用戶名mysql、密碼redhat和數據庫管理員密碼do280-admin。

    數據庫用戶名由database-user定義。此用戶的密碼由mysql secret密鑰定義。

    數據庫管理員密碼由database-root-password定義。

    10.10 創建secret

      1 [student@workstation secure-review]$ oc create secret generic mysql \
      2 --from-literal='database-user'='mysql' \
      3 --from-literal='database-password'='redhat' \
      4 --from-literal='database-root-password'='do280-admin'
      5 [student@workstation secure-review]$ oc get secret mysql -o yaml	#確認驗證secret


    10.11 部署應用

      1 [student@workstation secure-review]$ oc new-app --file=mysql-ephemeral.yml
      2 [student@workstation secure-review]$ oc get pods
      3 NAME            READY     STATUS    RESTARTS   AGE
      4 mysql-1-2lr7t   1/1       Running   0          31s


    10.12 轉發端口

      1 [student@workstation ~]$ oc port-forward mysql-1-2lr7t 3306:3306

    10.13 測試訪問

      1 [student@workstation ~]$ mysql -umysql -predhat -h127.0.0.1

    10.14 部署phpmyadmin應用


    使用內部倉庫registry.lab.example.com的image部署phpmyadmin:4.7容器。phpmyadmin:4.7容器需要名為PMA_HOST的環境變量來提供MySQL服務器的IP地址。

    使用模板創建一個基於FQND的MySQL pod的service。

    為使用模板創建的MySQL服務器pod使用服務FQDN,該模板是mysql.secure-review.svc.cluster.local。

      1 [student@workstation ~]$ oc new-app --name=phpmyadmin \
      2 --docker-image=registry.lab.example.com/phpmyadmin/phpmyadmin:4.7 \
      3 -e PMA_HOST=mysql.secure-review.svc.cluster.local






    結論:該命令會發出警告,提示需要root特權。默認情況下,OpenShift不支持使用操作系統的root用戶運行容器。

    10.15 查看pod

      1 [student@workstation ~]$ oc get pods
      2 NAME                 READY     STATUS    RESTARTS   AGE
      3 mysql-1-2lr7t        1/1       Running   0          8m
      4 phpmyadmin-1-v7tl7   0/1       Error     2          1m
      5 因為沒有root權限,因此部署失敗,需要提權。


    10.16 授予權限

      1 [student@workstation ~]$ oc login -u admin -p redhat			#使用管理員登錄
      2 [student@workstation ~]$ oc create serviceaccount phpmyadmin-account	#首先創建服務賬戶
      3 [student@workstation ~]$ oc adm policy add-scc-to-user anyuid -z phpmyadmin-account
      4 scc "anyuid" added to: ["system:serviceaccount:secure-review:phpmyadmin-account"]	#將服務帳戶與anyuid安全上下文關聯


    10.17 更新應用

      1 [student@workstation ~]$ oc patch dc phpmyadmin --patch='{"spec":{"template":{"spec":{"serviceAccountName": "phpmyadmin-account"}}}}'


    #更新負責管理phpmyadmin的dc資源,任何開發人員用戶都可以執行此操作。

    本環境中,相關操作命令可以從/home/student/DO280/labs/secure-review文件夾中的patch-dc.sh腳本運行或複製。

    10.18 確認驗證

      1 [student@workstation ~]$ oc login -u user-review -p redhat
      2 [student@workstation ~]$ oc get pods			#確認pod是否正常
      3 NAME                 READY     STATUS    RESTARTS   AGE
      4 mysql-1-2lr7t        1/1       Running   0          13m
      5 phpmyadmin-2-bdjvq   1/1       Running   0          1m


    10.19 暴露服務

      1 [student@workstation ~]$ oc expose svc phpmyadmin --hostname=phpmyadmin.apps.lab.example.com

    10.20 訪問測試

      1 [student@workstation ~]$ curl -s http://phpmyadmin.apps.lab.example.com

    10.21 確認及刪除

      1 [student@workstation ~]$ lab secure-review grade		#環境腳本判斷
      2 [student@workstation ~]$ oc login -u admin -p redhat
      3 [student@workstation ~]$ oc adm policy add-cluster-role-to-group \
      4 self-provisioner system:authenticated system:authenticated:oauth
      5 [student@workstation ~]$ oc delete project secure-review
      6 [student@workstation ~]$ ssh root@master htpasswd -D \
      7 /etc/origin/master/htpasswd user-review			#刪除用戶
      8 [student@workstation ~]$ oc delete user user-review		#刪除項目

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※教你寫出一流的銷售文案?

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • Linux 進程間通信(IPC)總結

    Linux 進程間通信(IPC)總結

    概述

    一個大型的應用系統,往往需要眾多進程協作,進程(Linux進程概念見附1)間通信的重要性顯而易見。本系列文章闡述了 Linux 環境下的幾種主要進程間通信手段。

    進程隔離

    進程隔離是為保護操作系統中進程互不干擾而設計的一組不同硬件和軟件的技術。這個技術是為了避免進程A寫入進程B的情況發生。 進程的隔離實現,使用了虛擬地址空間。進程A的虛擬地址和進程B的虛擬地址不同,這樣就防止進程A將數據信息寫入進程B。

    虛擬地址空間

    當創建一個進程時,操作系統會為該進程分配一個 4GB 大小的虛擬進程地址空間。之所以是 4GB ,是因為在 32 位的操作系統中,一個指針長度是 4 字節,而 4 字節指針的尋址能力是從 0x00000000~0xFFFFFFFF ,最大值 0xFFFFFFFF 表示的即為 4GB 大小的容量。與虛擬地址空間相對的,還有一個物理地址空間,這個地址空間對應的是真實的物理內存。要注意的是這個 4GB 的地址空間是“虛擬”的,並不是真實存在的,而且每個進程只能訪問自己虛擬地址空間中的數據,無法訪問別的進程中的數據,通過這種方法實現了進程間的地址隔離。

    針對 Linux 操作系統,將最高的1G字節(從虛擬地址 0xC0000000 到 0xFFFFFFFF )供內核使用,稱為內核空間,而較低的 3G 字節(從虛擬地址 0x00000000 到0xBFFFFFFF),供各個進程使用,稱為用戶空間。每個進程都可以通過系統調用進入到內核。其中在 Linux 系統中,進程的用戶空間是獨立的,而內核空間是共有的,進程切換時,用戶空間切換,內核空間不變

    創建虛擬地址空間目的是為了解決進程地址空間隔離的問題。但程序要想執行,必須運行在真實的內存上,所以,必須在虛擬地址與物理地址間建立一種映射關係。這樣,通過映射機制,當程序訪問虛擬地址空間上的某個地址值時,就相當於訪問了物理地址空間中的另一個值。人們想到了一種分段、分頁的方法,它的思想是在虛擬地址空間和物理地址空間之間做一一映射。這種思想理解起來並不難,操作系統保證不同進程的地址空間被映射到物理地址空間中不同的區域上,這樣每個進程最終訪問到的物理地址空間都是彼此分開的。通過這種方式,就實現了進程間的地址隔離。

     

    系統調用/內核態/用戶態

    雖然從邏輯上抽離出用戶空間和內核空間;但是不可避免的的是,總有那麼一些用戶空間需要訪問內核的資源;比如應用程序訪問文件,網絡是很常見的事情,怎麼辦呢?

    用戶空間訪問內核空間的唯一方式就是系統調用;通過這個統一入口接口,所有的資源訪問都是在內核的控制下執行,以免導致對用戶程序對系統資源的越權訪問,從而保障了系統的安全和穩定。用戶軟件良莠不齊,要是它們亂搞把系統玩壞了怎麼辦?因此對於某些特權操作必須交給安全可靠的內核來執行。

    當一個任務(進程)執行系統調用而陷入內核代碼中執行時,我們就稱進程處於內核運行態(或簡稱為內核態)此時處理器處於特權級最高的(0級)內核代碼中執行。當進程在執行用戶自己的代碼時,則稱其處於用戶運行態(用戶態)。即此時處理器在特權級最低的(3級)用戶代碼中運行。處理器在特權等級高的時候才能執行那些特權CPU指令。

    IPC 通信原理

    理解了上面的幾個概念,我們再來看看進程之間是如何實現通信的。

    通常的做法是消息發送方將要發送的數據存放在內存緩存區中,通過系統調用進入內核態。然後內核程序在內核空間分配內存,開闢一塊內核緩存區,調用 copy_from_user() 函數將數據從用戶空間的內存緩存區拷貝到內核空間的內核緩存區中。同樣的,接收方進程在接收數據時在自己的用戶空間開闢一塊內存緩存區,然後內核程序調用 copy_to_user() 函數將數據從內核緩存區拷貝到接收進程的內存緩存區。這樣數據發送方進程和數據接收方進程就完成了一次數據傳輸,我們稱完成了一次進程間通信。如下圖:

    進程間通信方式

    Linux 進程間基本的通信方式主要有:管道(pipe) (包括匿名管道和命名管道)、信號(signal)、消息隊列(queue)、共享內存、信號量和套接字。

    管道

    管道的實質是一個內核緩衝區(調用 pipe 函數來開闢),管道的作用正如其名,需要通信的兩個進程在管道的兩端,進程利用管道傳遞信息。管道對於管道兩端的進程而言,就是一個文件,但是這個文件比較特殊,它不屬於文件系統並且只存在於內存中。 Linux一切皆文件,操作系統為管道提供操作的方法:文件操作,用 fork 來共享管道原理。

    管道依據是否有名字分為匿名管道和命名管道(有名管道),這兩種管道有一定的區別。

    匿名管道有幾個重要的限制:

    1. 管道是半雙工的,數據只能在一個方向上流動,A進程傳給B進程,不能反向傳遞
    2. 管道只能用於父子進程或兄弟進程之間的通信,即具有親緣關係的進程。

    命名管道允許沒有親緣關係的進程進行通信。命名管道不同於匿名管道之處在於它提供了一個路徑名與之關聯,這樣一個進程即使與創建有名管道的進程不存在親緣關係,只要可以訪問該路徑,就能通過有名管道互相通信。

    pipe 函數接受一個參數,是包含兩個整數的數組,如果調用成功,會通過 pipefd[2] 傳出給用戶程序兩個文件描述符,需要注意 pipefd[0] 指向管道的讀端, pipefd[1] 指向管道的寫端,那麼此時這個管道對於用戶程序就是一個文件,可以通過 read(pipefd [0]);或者 write(pipefd [1]) 進行操作。pipe 函數調用成功返回 0,否則返回 -1.

    那麼再來看看通過管道進行通信的步驟:

    • 父進程創建管道,得到兩個文件描述符指向管道的兩端
    • 利用fork函數創建齣子進程,則子進程也得到兩個文件描述符指向同一管道
    • 父進程關閉讀端(pipe[0]),子進程關閉寫端pipe[1],則此時父進程可以往管道中進行寫操作,子進程可以從管道中讀,從而實現了通過管道的進程間通信。

         

    管道的特點:

    • 只能單向通信

    兩個文件描述符,用一個,另一個不用,不用的文件描述符就要 close

    • 只能血緣關係的進程進行通信

    • 依賴於文件系統

    • 生命周期隨進程

    • 面向字節流的服務

    面向字節流:數據無規則,沒有明顯邊界,收發數據比較靈活:對於用戶態,可以一次性發送也可以分次發送,當然接受數據也如此;而面向數據報:數據有明顯邊界,數據只能整條接受 

    • 管道內部提供了同步機制

    臨界資源: 大家都能訪問到的共享資源

    臨界區: 對臨界資源進行操作的代碼

    同步: 臨界資源訪問的可控時序性(一個操作完另一個才可以操作)

    互斥: 對臨界資源同一時間的唯一訪問性(保護臨界資源安全)

    說明:因為管道通信是單向的,在上面的例子中我們是通過子進程寫父進程來讀,如果想要同時父進程寫而子進程來讀,就需要再打開另外的管道;

    管道的讀寫端通過打開的文件描述符來傳遞,因此要通信的兩個進程必須從它們的公共祖先那裡繼承管道的件描述符。 上面的例子是父進程把文件描述符傳給子進程之後父子進程之 間通信,也可以父進程fork兩次,把文件描述符傳給兩個子進程,然後兩個子進程之間通信, 總之 需要通過fork傳遞文件描述符使兩個進程都能訪問同一管道,它們才能通信。

    四個特殊情況:

    1. 如果所有指向管道寫端的文件描述符都關閉了,而仍然有進程從管道的讀端讀數據,那麼管道中剩餘的數據都被讀取后,再次read會返回0,就像讀到文件末尾一樣

    2. 如果有指向管道寫端的文件描述符沒關閉,而持有管道寫端的進程也沒有向管道中寫數據,這時有進程從管道讀端讀數據,那麼管道中剩餘的數據都被讀取后,再次read會阻塞,直到管道中有數據可讀了才讀取數據並返回。

    3. 如果所有指向管道讀端的文件描述符都關閉了,這時有進程指向管道的寫端write,那麼該進程會收到信號SIGPIPE,通常會導致進程異常終止。

    4. 如果有指向管道讀端的文件描述符沒關閉,而持有管道寫端的進程也沒有從管道中讀數據,這時有進程向管道寫端寫數據,那麼在管道被寫滿時再write會阻塞,直到管道中有空位置了才寫入數據並返回。

    命名管道FIFO

    在管道中,只有具有血緣關係的進程才能進行通信,對於後來的命名管道,就解決了這個問題。FIFO 不同於管道之處在於它提供一個路徑名與之關聯,以 FIFO 的文件形式存儲於文件系統中。命名管道是一個設備文件,因此,即使進程與創建FIFO的進程不存在親緣關係,只要可以訪問該路徑,就能夠通過 FIFO 相互通信。值得注意的是, FIFO (first input first output) 總是按照先進先出的原則工作,第一個被寫入的數據將首先從管道中讀出。

    命名管道的創建

    創建命名管道的系統函數有兩個: mknod 和 mkfifo。兩個函數均定義在頭文件 sys/stat.h,
    函數原型如下:

    #include <sys/types.h>
    #include <sys/stat.h>
    int mknod(const char *path,mode_t mod,dev_t dev);
    int mkfifo(const char *path,mode_t mode);

    函數 mknod 參數中 path 為創建的命名管道的全路徑名: mod 為創建的命名管道的模指明其存取權限; dev 為設備值,該值取決於文件創建的種類,它只在創建設備文件時才會用到。這兩個函數調用成功都返回 0,失敗都返回 -1。

    命名管道打開特性:

    1. 如果用只讀打開命名管道,open 函數將阻塞等待直至有其他進程以寫的方式打開這個命名管道,如果沒有進程以寫的方式發開這個命名管道,程序將停在此處

    2. 如果用只寫打開命名管道,open 函數將阻塞等到直至有其他進程以讀的方式打開這個命名管道,如果沒有進程以讀的方式發開這個命名管道,程序將停在此處;

    3. 如果用讀寫打開命名管道,則不會阻塞(但是管道是單向)

    System V IPC   

    IPC(Inter-Process Communication)是指多個進程之間相互通信,交換信息的方法,System V 是 Unix 操作系統最早的商業發行版,由 AT&T(American Telephone & Telegraph)開發。System V IPC 是指 Linux 引入自 System V 的進程通信機制,一共有三種:

    • 信號量,用來管理對共享資源的訪問;

    • 共享內存,用來高效地實現進程間的數據共享;

    • 消息隊列,用來實現進程間數據的傳遞。

    這三種統稱 IPC 資源,每個 IPC 資源都是請求時動態創建的,都是永駐內存,除非被進程显示釋放,都是可以被任一進程使用。每個 IPC 資源都使用一個 32 位的 IPC 關鍵字和 32 位的 IPC 標識符,前者類似文件系統中的路徑名,由程序自由定製,後者類似打開文件的文件描述符,由內核統一分配,在系統內部是唯一的,當多個進程使用同一個IPC資源通信時需要該資源的 IPC 標識符。     

    創建新的 IPC 資源時需要指定 IPC 關鍵字,如果沒有與之關聯的 IPC 資源,則創建一個新的 IPC 資源;如果已經存在,則判斷當前進程是否具有訪問權限,是否超過資源使用限制等,如果符合條件則返回該資源的 IPC 標識符。為了避免兩個不同的 IPC 資源使用相同的 IPC 關鍵字,創建時可以指定IPC關鍵字為 IPC_PRIVATE,由內核負責生成一個唯一的關鍵字。   

    創建新的 IPC 資源時最後一個參數可以包括三個標誌,PC_CREAT 說明如果IPC資源不存在則必須創建它,IPC_EXCL 說明如果資源已經存在且設置了 PC_CREAT 標誌則創建失敗,IPC_NOWAIT 說明訪問 IPC 資源時進程從不阻塞。 

    信號量

    信號量(semaphore)是一種用於提供不同進程之間或者一個給定的不同線程間同步手段的原語。信號量多用於進程間的同步與互斥,簡單的說一下同步和互斥的意思:

    同步:處理競爭就是同步,安排進程執行的先後順序就是同步,每個進程都有一定的先後執行順序。

    互斥:互斥訪問不可共享的臨界資源,同時會引發兩個新的控制問題(互斥可以說是特殊的同步)。

    競爭:當併發進程競爭使用同一個資源的時候,我們就稱為競爭進程。

    共享資源通常分為兩類:一類是互斥共享資源,即任一時刻只允許一個進程訪問該資源;另一類是同步共享資源,即同一時刻允許多個進程訪問該資源;信號量是解決互斥共享資源的同步問題而引入的機制。

    下面說一下信號量的工作機制,可以直接理解成計數器(當然其實加鎖的時候肯定不能這麼簡單,不只只是信號量了),信號量會有初值(>0),每當有進程申請使用信號量,通過一個 P 操作來對信號量進行-1操作,當計數器減到 0 的時候就說明沒有資源了,其他進程要想訪問就必須等待(具體怎麼等還有說法,比如忙等待或者睡眠),當該進程執行完這段工作(我們稱之為臨界區)之後,就會執行 V 操作來對信號量進行 +1 操作。

    • 臨界區:臨界區指的是一個訪問共用資源(例如:共用設備或是共用存儲器)的程序片段,而這些共用資源又無法同時被多個線程訪問的特性。

    • 臨界資源:只能被一個進程同時使用(不可以多個進程共享),要用到互斥。

    我們可以說信號量也是進程間通信的一種方式,比如互斥鎖的簡單實現就是信號量,一個進程使用互斥鎖,並通知(通信)其他想要該互斥鎖的進程,阻止他們的訪問和使用。

    當有進程要求使用共享資源時,需要執行以下操作:

    1. 系統首先要檢測該資源的信號量;

    2. 若該資源的信號量值大於 0,則進程可以使用該資源,此時,進程將該資源的信號量值減1;

    3. 若該資源的信號量值為 0,則進程進入休眠狀態,直到信號量值大於 0 時進程被喚醒,訪問該資源;

           當進程不再使用由一個信號量控制的共享資源時,該信號量值增加 1,如果此時有進程處於休眠狀態等待此信號量,則該進程會被喚醒

    每個信號量集都有一個與其相對應的結構,該結構定義如下:

    /* Data structure describing a set of semaphores.  */  
    struct semid_ds  
    {  
        struct ipc_perm sem_perm;   /* operation permission struct */  
        struct sem *sem_base;       /* ptr to array of semaphores in set */  
        unsigned short sem_nsems;   /* # of semaphores in set */  
        time_t sem_otime;           /* last-semop() time */  
        time_t sem_ctime;           /* last-change time */  
    };  
      
    /* Data structure describing each of semaphores.  */  
    struct sem  
    {  
        unsigned short semval;  /* semaphore value, always >= 0 */  
        pid_t          sempid;  /* pid for last successful semop(), SETVAL, SETALL */  
        unsigned short semncnt; /* # processes awaiting semval > curval */  
        unsigned short semzcnt; /* # processes awaiting semval == 0 */  
    };  

    信號量集的結構圖如下所示:

    消息隊列

    消息隊列,是消息的鏈接表,存放在內核中。一個消息隊列由一個標識符(即隊列 ID)來標識。其具有以下特點:

    1. 消息隊列是面向記錄的,其中的消息具有特定的格式以及特定的優先級。

    2. 消息隊列獨立於發送與接收進程。進程終止時,消息隊列及其內容並不會被刪除。

    3. 消息隊列可以實現消息的隨機查詢,消息不一定要以先進先出的次序讀取,也可以按消息的類型讀取。

    原型

    1 #include <sys/msg.h>
    2 // 創建或打開消息隊列:成功返回隊列ID,失敗返回-1
    3 int msgget(key_t key, int flag);
    4 // 添加消息:成功返回0,失敗返回-1
    5 int msgsnd(int msqid, const void *ptr, size_t size, int flag);
    6 // 讀取消息:成功返回消息數據的長度,失敗返回-1
    7 int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
    8 // 控制消息隊列:成功返回0,失敗返回-1
    9 int msgctl(int msqid, int cmd, struct msqid_ds *buf);

    在以下兩種情況下,msgget 將創建一個新的消息隊列:

    • 如果沒有與鍵值key相對應的消息隊列,並且flag中包含了IPC_CREAT標誌位。

    • key參數為IPC_PRIVATE

    函數msgrcv在讀取消息隊列時,type參數有下面幾種情況:

    • type == 0,返回隊列中的第一個消息;

    • type > 0,返回隊列中消息類型為 type 的第一個消息;

    • type < 0,返回隊列中消息類型值小於或等於 type 絕對值的消息,如果有多個,則取類型值最小的消息。

    可以看出,type 值非 0 時用於以非先進先出次序讀消息。也可以把 type 看做優先級的權值。

    共享內存

    共享內存是 System V 版本的最後一個進程間通信方式。共享內存,顧名思義就是允許兩個不相關的進程訪問同一個邏輯內存,共享內存是兩個正在運行的進程之間共享和傳遞數據的一種非常有效的方式。不同進程之間共享的內存通常為同一段物理內存。進程可以將同一段物理內存連接到他們自己的地址空間中,所有的進程都可以訪問共享內存中的地址。如果某個進程向共享內存寫入數據,所做的改動將立即影響到可以訪問同一段共享內存的任何其他進程。

    特別提醒:共享內存並未提供同步機制,也就是說,在第一個進程結束對共享內存的寫操作之前,並無自動機制可以阻止第二個進程開始對它進行讀取,所以我們通常需要用其他的機制來同步對共享內存的訪問,例如信號量。

    共享內存的通信原理
    在 Linux 中,每個進程都有屬於自己的進程控制塊(PCB)和地址空間(Addr Space),並且都有一個與之對應的頁表,負責將進程的虛擬地址與物理地址進行映射,通過內存管理單元(MMU)進行管理。兩個不同的虛擬地址通過頁表映射到物理空間的同一區域,它們所指向的這塊區域即共享內存。

    共享內存的通信原理示意圖:

     

    對於上圖我的理解是:當兩個進程通過頁表將虛擬地址映射到物理地址時,在物理地址中有一塊共同的內存區,即共享內存,這塊內存可以被兩個進程同時看到。這樣當一個進程進行寫操作,另一個進程讀操作就可以實現進程間通信。但是,我們要確保一個進程在寫的時候不能被讀,因此我們使用信號量來實現同步與互斥。

    對於一個共享內存,實現採用的是引用計數的原理,當進程脫離共享存儲區后,計數器減一,掛架成功時,計數器加一,只有當計數器變為零時,才能被刪除。當進程終止時,它所附加的共享存儲區都會自動脫離。

    為什麼共享內存速度最快?

    藉助上圖說明:Proc A 進程給內存中寫數據, Proc B 進程從內存中讀取數據,在此期間一共發生了兩次複製

    (1)Proc A 到共享內存       (2)共享內存到 Proc B

    因為直接在內存上操作,所以共享內存的速度也就提高了。

    共享內存的接口函數以及指令

    查看系統中的共享存儲段

    ipcs -m

    刪除系統中的共享存儲段

    ipcrm -m [shmid]

    shmget ( ):創建共享內存

    int shmget(key_t key, size_t size, int shmflg);

    [參數key]:由ftok生成的key標識,標識系統的唯一IPC資源。

    [參數size]:需要申請共享內存的大小。在操作系統中,申請內存的最小單位為頁,一頁是4k字節,為了避免內存碎片,我們一般申請的內存大小為頁的整數倍。

    [參數shmflg]:如果要創建新的共享內存,需要使用IPC_CREAT,IPC_EXCL,如果是已經存在的,可以使用IPC_CREAT或直接傳0。

    [返回值]:成功時返回一個新建或已經存在的的共享內存標識符,取決於shmflg的參數。失敗返回-1並設置錯誤碼。

    shmat ( ):掛接共享內存

    void *shmat(int shmid, const void *shmaddr, int shmflg);

    [參數shmid]:共享存儲段的標識符。

    [參數*shmaddr]:shmaddr = 0,則存儲段連接到由內核選擇的第一個可以地址上(推薦使用)。

    [參數shmflg]:若指定了SHM_RDONLY位,則以只讀方式連接此段,否則以讀寫方式連接此段。

    [返回值]:成功返回共享存儲段的指針(虛擬地址),並且內核將使其與該共享存儲段相關的shmid_ds結構中的shm_nattch計數器加1(類似於引用計數);出錯返回-1。

    shmdt ( ):去關聯共享內存:當一個進程不需要共享內存的時候,就需要去關聯。該函數並不刪除所指定的共享內存區,而是將之前用shmat函數連接好的共享內存區脫離目前的進程。

    int shmdt(const void *shmaddr);

    [參數*shmaddr]:連接以後返回的地址。

    [返回值]:成功返回0,並將shmid_ds結構體中的 shm_nattch計數器減1;出錯返回-1。

    shmctl ( ):銷毀共享內存

    int shmctl(int shmid, int cmd, struct shmid_ds *buf);

    [參數shmid]:共享存儲段標識符。

    [參數cmd]:指定的執行操作,設置為IPC_RMID時表示可以刪除共享內存。

    [參數*buf]:設置為NULL即可。

    [返回值]:成功返回0,失敗返回-1。

    POSIX 消息隊列   

    POSIX 消息隊列是 POSIX 標準在 2001 年定義的一種 IPC 機制,與 System V 中的消息隊列相比有如下差異:

    • 更簡單的基於文件的應用接口,Linux 通過 mqueue 的特殊文件系統來實現消息隊列,隊列名跟文件名類似,必須以”/”開頭,每個消息隊列在文件系統內都有一個對應的索引節點,返回的隊列描述符實際是一個文件描述符

    • 完全支持消息優先級,消息在隊列中是按照優先級倒序排列的(即0表示優先級最低)。當一條消息被添加到隊列中時,它會被放置在隊列中具有相同優先級的所有消息之後。如果一個應用程序無需使用消息優先級,那麼只需要將msg_prio指定為0即可。

    • 完全支持消息到達的異步通知,當新消息到達且當前隊列為空時會通知之前註冊過表示接受通知的進程。在任何一個時刻都只有一個進程能夠向一個特定的消息隊列註冊接收通知。如果一個消息隊列上已經存在註冊進程了,那麼後續在該隊列上的註冊請求將會失敗。可以給進程發送信號或者另起一個線程調用通知函數完成通知。當通知完成時,註冊即被撤銷,進程需要繼續接受通知則必須重新註冊。

    • 用於阻塞發送與接收操作的超時機制,可以指定阻塞的最長時間,超時自動返回 

    套接字:

    套接字是更為基礎的進程間通信機制,與其他方式不同的是,套接字可用於不同機器之間的進程間通信。

    有兩種類型的套接字:基於文件的和面向網絡的。

    • Unix 套接字是基於文件的,並且擁有一個“家族名字”–AF_UNIX,它代表地址家族 (address family):UNIX。

    • 第二類型的套接字是基於網絡的,它也有自己的家族名字–AF_INET,代表地址家族 (address family):INTERNET

    不管採用哪種地址家族,都有兩種不同的套接字連接:面向連接的和無連接的。

    • 面向連接的套接字 (SOCK_STREAM):進行通信前必須建立一個連接,面向連接的通信提供序列化的、可靠地和不重複的數據交付,而沒有記錄邊界。

    這意味着每條信息可以被拆分成多個片段,並且每個片段都能確保到達目的地,然後在目的地將信息拼接起來。

    實現這種連接類型的主要協議是傳輸控制協議 (TCP)。

    • 無連接的套接字 (SOCK_DGRAM):在通信開始之前並不需要建立連接,在數據傳輸過程中並無法保證它的順序性、可靠性或重複性。

    然而,數據報確實保存了記錄邊界,這就意味着消息是以整體發送的,而並非首先分成多個片段。

    由於面向連接的套接字所提供的保證,因此它們的設置以及對虛擬電路連接的維護需要大量的開銷。然而,數據報不需要這些開銷,即它的成本更加“低廉”

    實現這種連接類型的主要協議是用戶數據報協議 (UDP)。

    信號

    信號是軟件層次上對中斷機制的一種模擬,是一種異步通信方式,進程不必通過任何操作來等待信號的到達。信號可以在用戶空間進程和內核之間直接交互,內核可以利用信號來通知用戶空間的進程發生了哪些系統事件。

    信號來源:

    信號事件的發生有兩個來源:硬件來源,比如我們按下了鍵盤或者其它硬件故障;軟件來源,最常用發送信號的系統函數是 kill, raise, alarm 和 setitimer 以及 sigqueue 函數,軟件來源還包括一些非法運算等操作。

    進程對信號的響應:

    進程可以通過三種方式來響應信號:

    • 忽略信號,即對信號不做任何處理,但是有兩個信號是不能忽略的:SIGKLL 和 SIGSTOP;

    • 捕捉信號,定義信號處理函數,當信號發生時,執行相應的處理函數;

    • 執行缺省操作,Linux 對每種信號都規定了默認操作。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

    ※教你寫出一流的銷售文案?

    FB行銷專家,教你從零開始的技巧