整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HTML的一些常用的語法寫法

          、 結構

          一、標記<Html> 建立HTML文檔

          <Head> 設置網頁頭部和其它信息

          <Body> 設計文件格式及內文所在<Body> 元素的屬性

          Text 設置頁面文字的送顔色 Bgcolor 設置頁面背景的顡色

          Background 設置頁面的背景圖像 Link設置頁面黙認的顔色

          Bgproperties 設置頁面的背景圖像為固定,不隨頁面的滾動而滾動

          Alink 設置鼠標正在單擊時候的鏈接顔色 Vlink 設置訪問過后的鏈接顔色

          Topmargin 設置頁面的上邊距 Leftmargin 設置頁面的左邊距

          二、頭部

          標記 <Base> 當前文檔的URL全稱 <Title>設置顯示在瀏覽器在上方的標題內容

          <Isindex> 表明該文檔是一個可用于檢索的網關腳本

          <Meta> 有關文檔本身的信息,例如用于查詢的關鍵詞,用于獲取該文檔的有效期等

          <Style> 設置CSS層疊樣式表的內容

          <link> 設置外部文件的鏈接 <script> 設置頁面中程序腳本的內容

          <Mate> 標記屬性

          Http-Equiv 生成一個HTTP標題域,它的取值與另一個屬性相同,

          例如Http-Equiv=Expires,實際取值由Content確定

          Name 如果元數據是以關鍵字/取值的形式出現的,Name 表示鍵字,

          如Author或ID

          Content 關鍵字/取值的內容

          三、文字

          文字標記 <HNumber>……<1HNumber> Number=1.2.3.4.5.6

          分別指1至6級標題

          <Font>文字

          文字的修飾標記 <B>/<strong> 粗體 <I>/<Em>/<cite> 斜體

          <Sup>上標 <sub>下標 <Big>大字號 <small>小字號

          <U>下劃線 <S>/<strike>刪除線 <Address>地址

          <Tt>打字機文字 <Blink>閃爍文字(只適用于Netscape瀏覽器)

          <Code>/<samp>等寬 <kbd>鍵盤輸入文字 <Var>聲明變量

          <Fant>標記的屬性

          Face 字體 Size字號 Color顔色

          四.列表

          列表標記 <Ul>無序列表 <Ol>有序列表 <Dir>回錄列表 <Dl>定義列表

          <Meru>菜單列表 <Dt>·<Dd>定義列表的標記 <Li>列表項目的標記

          <Ul><Ol>標記的屬性 Type設置列表類型 start設置列表起始屬性

          Type的屬性值 1 數字 a 小寫字母 A 大寫字母 i小寫羅馬數字

          I 大寫羅馬數字 Disc ● Circle ○ square □

          五.鏈接

          鏈接標記 <A> 鏈接

          <A>標記的屬性 Href 指定鏈接地址 Name給鏈接命名

          Title設置鏈接提示文字 Target指定鏈接的目標窗口

          Target屬性值 -parent在上一級窗口中打開。一般使用分幀的框架頁會經常使用

          -bank在新窗口中打開

          -self在同一個幀或窗口中打開.這項一般不用設置

          Href屬性值 http:// 進入萬維網站點 news://啟動新聞討論

          ftp:// 進入文件傳輸服務器 mailto:// 啟動新聞討論組

          telnet:// 啟動telnet方式 gopher://訪問一個gopher服務器

          六.圖片

          圖片標記 <Img>圖片 <Map>圖像映射 <Area>圖像映射中定義區域

          <lmg>標記的屬性 src圖像的源文件 Alt提示文字 Width寬度

          Height高度 Vspace垂直間距 Hspace水平間距 Align排列 Border邊框

          Align屬性值 Top文字的中間線居于圖片上方 Middle文字的中間線居于圖片中間

          Bottom文字的中間線居于圖片底部 Left 圖片在文字的左側

          Right圖片在文字的右側 Absbottom文字的底線居于圖片底部

          Absmiddle文字的底線居于圖片中間 Baseline英文文字基線對齊

          Texttop英文文字上邊線對齊

          Shape屬性值

          Rect矩形區域 Circle橢圓形區域 Poly多邊形區域

          七.表格

          1.表格標記 <Table>…</Table>表格標記 <Tr>…</Tr>行標記

          <Td>…</Td>單元格標記 <Th>表頭標記

          <Table>標記屬性 Bordercolor 表格邊框色 Borde表格邊框的寬度

          Bordercolorlight 表格邊框亮邊框色(左上邊框顔色)

          Bordercolordark 表格暗邊框色(右下邊框顔色)

          Bordercolor 行的邊框顔色 Width表格的寬度 Height表格的高度

          Bgcolor表格的背景顔色 Background表格的背圖像

          <Tr>標記屬性 Align行內容的水平對齊 Valign 行內容的垂直對齊

          Bgcolor 行的背景顔色 Background 行的背景圖像

          Bordercolor 行的邊框顔色 Bordercolorlight 行的亮邊框顔色

          Bordercolordark 行的暗邊框顔色

          <Td>標記屬性 Align單元內容的水平對齊 Valign單元格內容的垂直對齊

          Bgcolor 單元格的背景顔色 Background 單元格的背景圖像

          Bordercolor單元格的背景顔色 Bordercorlorlight單元格的亮邊框顔色

          Brodercolordark 單元格的暗邊框顔色 Width 單元格的寬度

          Height單元格的高度

          <Th>標記屬性 Align表頭內容的水平對齊 Valign表頭內容的垂直對齊

          Bgcolor 表頭的背景顔色 Background表頭的背景圖像

          Bordercolor表頭的邊框顔色 Bordercolorlight 表頭的亮邊框顔色

          Bordercolordark 表頭的暗邊框顔色 Width 表頭的寬度 Height 表頭的高度

          八.表單

          1.表單標記 <Form>表單標記 <Input>表單輸入標記

          <select>菜單和列表標記 <Option>菜單和列表項目標記

          2.屬性 <Form> Name表單的名稱

          Method 定義表單結果從瀏覽器傳送到服務器的方法,一般有兩種方法:get,post

          Action 用來定義表單處理程序(一個Asp,CGI等程序)的位置(相對地址或絕對地址)

          <lnput>標記屬性 Name 域的名稱 Type域的類型

          Maxlength 域的最大輸入字符數 size域的寬度 Value 域的默認值

          <Select>標記屬性 Name 菜單和列表的名稱 size 顯示的選項數目

          Multiple 列表中的項目多選 Value 選項值 selected默認選項

          <Texrarea>標記屬性 Name 文字域的名稱 Rows文字域的行數

          Cols 文字域的列數 Value 文字域的默認值

          Type屬性值 Text 文字域 Password 密碼域 File 文件域

          Checkbox復選框 Redio單選框 Button普通按扭

          Submit 提交按鈕 Reset重置按鈕 Hidden隱藏域Image圖像域

          九.滾動

          滾動標記 <Marquee>

          <Marquee>標記屬性 Direction 滾動方向 up 文字向上滾動 Left文字向左滾動

          Behavior 滾動方式 Scroll 循環往復

          Side 只做一次滾動

          Alternate 交替進行滾動

          ScrollAmount 滾動速度

          ScrollDelay 滾動延遲

          Trim函數用來剔除首尾空格

          十.框架

          1.標記 <Frameset> 框架邊框標記 <Frame> 框架標記 <Iframe>浮動框架標記

          <Frameset>標記屬性 Cols列 Rows行

          <Frame> 標記屬性 src框架中顯示頁面源文件的路徑

          FrameBorder 框架邊框顯標屬性 FrameSpacing框架邊框寬度屬性

          Scrolling框架滾動條顯示屬性 NoResize 框架尺寸調整屬性

          BorderColor 框架邊框顔色屬性 MarginWidt 框架邊框緣寬度屬性

          MarginHerght框架邊緣高度屬性

          <1frame> 標記屬性 src浮動框架中顯示頁面源文件的路徑

          Width 浮動框架的寬度 Height 浮動框架的高度

          Name 浮動框架的名稱

          Align 浮動框架的排列方式 Left表示居左 Center表示居中 Right表示居右

          FrameBorder 框架邊框顯示屬性 FrameSpacing 框架寬度屬性

          Scrolling 框架滾動條顯示屬性 ( yes顯示 No不顯示 Auto根據頁面的長度自動判斷是否晶粒示滾動條

          NoResize 框架尺寸調整屬性 BorderColor框架的顔色

          MarginWidth 框架邊緣寬度屬性 MarginHeight 框架邊緣高度屬性

          插入刷新

          步驟:1.選擇"查看/文件頭內容"

          2.在插入面板上,打開HTML選項卡

          優化代碼

          打開文件窗口,執行"命令、清理HTML"命令

          文本換行:Enter 行距較大

          Enter + Shift 行距較小

          插入水平線設置顔色:單擊屬性面板中的快捷標簽編輯器按鈕

          在代碼中鍵入"color = #顔色值"

          當圖像無法顯示時將顯示這段文字:

          圖像屬性中的替代→輸入文字

          插入鼠標經過圖像:準備兩張圖像

          在文件窗口中,將光標放置于需要翻轉圖像位置→插入工具欄中單擊鼠標經過圖像

          Ⅱ.使用導航條:

          在"常用"對象組中,單擊"圖像"小三角→導航條

          插入圖像占位符:圖像小三角→圖像占位符

          Flash動畫的背景實現透明 參數wmode 值 transparent

          插入 Java Applet

          插入表單

          插入表單域:對象面板上"表單"→插入表單

          插入文本域:單擊面板上的插入文本域. 初始值 = 打開時顯于的文字

          插入密碼框:在屬性面板上選擇密碼

          插入多行文本域:在類型后選擇多行

          插入隱藏域:對象面板→插入隱藏域

          插入按鈕:標簽用來設置按鈕上顯示的文本

          插入圖像提交按鈕=圖像域:

          插入文件上傳按鈕=文件域:

          插入單選框

          插入單選按鈕組:Label文字說明 Value 單選按鈕的值

          插入復選框

          菜單/插入列表:列表值→

          插入跳轉菜單:(

          制作網頁鏈接

          URL統一資源定位器

          目標:_blank在一個新的未命名的瀏覽器窗口中打開

          _parent如果是嵌套的框架,鏈接會在父框架或窗口中打開,否則=_top

          _top在完整的瀏覽器中打開

          創建搜索頁

          運行中輸入:

          Inetmgr (IIS

          Odbcad32 (odbc

          Asp對象

          Applicatipn 在給定的應用程序的所有用戶間共享信息,并在服務器運行期間持久地保存數據。

          集合: Contents

          staticObjects

          Item(變量值)=設置資料變量的值

          Key(變量名稱)=設置資料變量的名稱

          Count(變量資料的數量)=表示

          Coutents集合中資料的總數量

          方法: Lock

          Unlock

          事件: Applicatipn_Onstart

          Application_OnEnd

          Session 存儲特定的用戶會話所需的信息

          屬性:CodePage

          LCID

          SessionID

          Timeout

          集合:Contents

          StaticObjects

          方法:Abandon

          事件:Session_Onstart

          Session_OnEnd

          Response 用來控制發送給用戶的信息,包括直接發送信息給瀏覽器,重定位瀏覽器到另一個URL或設置Cookie值

          屬性: Buffer

          CacheControl

          Charset

          ContentType

          Expires

          ExpiresAbsolute

          IsClientConnected

          PICS

          Status

          集合: Cookies

          方法: AddHeader

          AppendToLog

          BinaryWrite

          Clear

          End

          Flush

          Redirect

          Write

          Request 訪問任何基于HTTP請求傳遞的信息,常見的有從HTML表單用Post方法或Get方法傳遞的參數,Cookie或用戶認證等。

          屬性: TotalBytes

          集合: ClientCertificate

          Cookies

          Form

          QueryString

          ServerVaiables

          方法: BinaryRead

          Server 提供對服務器方法和屬性的訪問

          屬性: ScriptTimeout

          集合: 無

          方法: CreatObject

          HTMLEncode

          MapPath

          URLEncode

          Recordset

          MoveNext 將前數據記錄移至下一條

          MovePrevious 將當前數據記錄移至上一條

          MoveFirst 將當前數據記錄移至第一條

          MoveLast 將當前數據記錄移至最后一條

          AbsolutePosition=N 將當前數據記錄移至第N條

          EOF 當前數據記錄是否移過了最后一條(發生于向下移動時)

          BOF 當前數據記錄是否移過了第一條 (發生于向上移動時)

          VBScript 運算符

          算術運算符

          指數 取負 乘法 除法 加法 減法 取模 連接 整數除法

          ∧ - * / ﹢ ﹣ Mod & \

          比較運算符

          相等 不相等 小于 大于 小于或等于 大于或等于 對象相象

          = <> < > <= >= IS

          邏輯運算符

          邏輯非 邏輯與 邏輯或 異或 邏輯等于 邏輯蘊含

          Not And Or Xor Eqv Imp

          過去十年間,中國經濟取得了長足發展,也為其他國家的發展提供了借鑒。這背后有哪些原因?近日,巴西前旅游部部長、現任清華大學教授福鑫(Alessandro Teixeira)做客中國日報《連線》欄目,帶來他對中國發展和相關問題的解讀。

          中國的發展不是威脅

          Q:China has achieved many economic milestones over the past decade, but the Western politicians' saying "China is a threat to the world" has followed all the way. What is your opinion on this?

          過去十年間,中國經濟取得了許多里程碑式的成就。與之相伴,西方政治家就“中國威脅論”喋喋不休。對于這個現象,您怎么看?

          A:I think we need to analyze this statement very carefully. When you say "Western", I think it’s too heavy, it's not Western, maybe mainly it's America and some allied European countries. Because if you go to South America, nobody's talking about China being a threat. If you go to Africa, nobody is talking about it as a trap. People who tell you that or people who are vocal about that are from some countries in the Europe, not all of them, and then there's the United States. So the question is, a threat to whom?

          我認為這個說法值得仔細分析。當你說“西方”的時候,我認為太廣泛了。你所謂的“西方”,我認為不是西方,而主要是美國和其部分歐洲盟友。在南美,沒人談論中國是個威脅。非洲也沒人討論“債務陷阱”。一直拿“中國威脅論”來說事的,是少數幾個歐洲國家,不是全部,以及美國。所以問題應該是,中國對誰產生了威脅?

          Another question is, why is China a threat? Maybe because the United States doesn't want to compete with anybody else? And China represents, not because China wants to, but represents competition to the US in terms of technology, competition to the US in terms of production. So those are the main elements. I don't see China being a threat to anyone. China's foreign policy, respects sovereignty of every single country. China never invades, never declares war. We are talking about competition in a very narrow field, that is economics.

          問題之二在于:為何說中國是一個威脅?或許是因為美國不想和其他國家競爭?不是中國想要去競爭,而是中國在科技、制造的實力使其被美國視為競爭對手。所以這些才是關鍵元素。我認為中國不會對任何國家產生威脅。中國的外交政策尊重每一個國家的主權。中國從不發起侵略,也從不對外宣戰。我們所說的競爭僅限于特定的領域,就是經濟領域。

          And that's natural because China wants to achieve development. And when to achieve development, you need to have, as President Xi Jinping says, dual circulation, internal market, external market. And if competition is not good, I don't understand, because the United States loves to say that they want to have free competition. So let China compete in the international market, so I don't see a threat in any way. I can see competition, I can see China trying to gain the market.

          但這是很自然的事,中國要發展,想要發展,就要如習近平主席所說,實現雙循環,在外部和內部的市場有機循環起來。如果競爭不是好事,那讓我不明白的是,為什么美國還總是喜歡自我標榜“自由競爭”?所以,讓中國在國際市場上競爭,無論如何,我都不認為中國的發展是一種威脅,我看到的是競爭,是中國在努力爭取市場。

          “一帶一路”倡議

          不是中國的“馬歇爾計劃”

          Q:The Diplomat compared China's BRI to the US's Marshall Plan in a 2016 article. What is your estimation of BRI?

          《外交學者》雜志在一篇2016年的文章中將中國的“一帶一路”倡議比作美國的馬歇爾計劃。您怎么看待“一帶一路”倡議?

          A:It's completely different. Marshall Plan is a plan for reconstruction and for economic fostering. BRI is not that.

          “一帶一路”倡議和馬歇爾計劃完全不同。馬歇爾計劃旨在戰后重建和復蘇經濟。“一帶一路”不是。

          Many people would say that the Belt and Road Initiative is a Chinese initiative. Many people say that it’s a way for China to increase trade or increase investment outside. The way I see it is a little different. I see it as a cooperation platform.

          許多人認為“一帶一路”倡議是中國倡議。也有許多人說它是中國增長貿易、促進外部投資的方式。我的看法稍許不同。我認為“一帶一路”倡議是一個合作平臺。

          So when we have Latin American countries and there's a discussion, how would Latin America take part in it? How could Latin America engage better? And again, the point that I'd like to stress is that Latin America can engage with many other countries other than China. Because China had the idea to create a platform, but China doesn't want to monopolize it and keep the Belt and Road Initiative to itself. No, it wants to spread around the world as a cooperation platform. You want to be part of BRI. That's fine. If you're not, it's okay. It's your option.

          所以,當拉丁美洲國家加入了“一帶一路”倡議后,當地就開始進行關于拉丁美洲國家如何參與該倡議的討論,拉丁美洲國家怎樣更好地參與進來?我想再次強調一點,這并不是只與中國打交道,因為中國只是創造了一個平臺,中國并不希望一家獨大,將“一帶一路”倡議占為己有。不,中國是想向世界提供一個合作平臺。你想要加入,那非常棒。你不想加入,沒問題,你有選擇的自由。

          What I am saying is that if you're part of BRI, you would have enjoyed a club that can invest together, can do trade together, can share different cultural elements together, can participate in discussion of the digital economy, digital transformation, societal transformations. So that's the important point.

          我想說的是,如果你是“一帶一路”倡議的成員,你就好像加入了一個俱樂部,大家一起投資,一起貿易,一起分享不同文化,一起參與數字經濟、數字轉型、社會轉型的討論。這點非常重要。

          I've heard people say many times, if you're part of the BRI, China will invest in you, will buy from you. No, that's not the case. China never said that. What China always said is that we are creating, we are sharing a vision of the world of humankind where we want development and prosperity. BRI is a tool that can help us to achieve that. China never said that the only tool is our tool. There is no need for these adjectives in the discussion. What we have in the discussion is something that could help the world.

          我多次聽到別人說,如果你參與共建“一帶一路”,那么中國就會向你投資、向你買東西。不,并非如此。中國從來沒說過這樣的話。中國一直說我們要創建人類命運共同體,共同發展,共同繁榮。“一帶一路”倡議就是幫我們實現它的工具。中國從沒說過我們的工具是唯一的工具。這些話從沒出現在討論中。我們在討論一些對世界有益的事情。

          中美兩國不會脫鉤

          Q:In the context of globalization, what is your opinion about the so-called China-US decoupling?

          在全球化背景下,您如何看待所謂的“中美脫鉤”?

          A:In my opinion, it's very, very hard to have a decoupling. When you are the first and second economies, there is no possibility of decoupling. Why? Because you are integrated, not fully, in some value chains, in some supply chains, you are completely integrated.

          在我看來,中美兩國很難脫鉤。兩者作為世界第一大和第二大經濟體,兩者不可能做到脫鉤。為什么呢?因為中美已經在一些價值鏈、供應鏈中相互融合,已經融合在一起。

          But of course, if you are two largest economies in the world, there is no possibility of decoupling. So I think what the US Trade Representative says in Singapore is the right thing. You cannot divorce. You can realign, you can restrategize, but you cannot divorce. There is no such thing in decoupling. There is no such thing in decoupling in terms of macro economics. There is no such thing of decoupling in terms of technology. Because they are already integrated.

          當然,作為世界上最大的兩個經濟體,兩者不可能做到脫鉤。所以,我贊同美國貿易代表戴琪在新加坡所說的話,中美兩國不能脫鉤。兩個國家可能重新調整關系,可能重新部署規劃,但是不可能脫鉤。不存在脫鉤,從宏觀經濟而言,脫鉤不存在,從科技層面而言,脫鉤也不存在,因為兩國已經緊密結合。

          It took a long time, almost two decades, three decades for this integration between the American economy and the Chinese economy. You can not just do it by a presidential order, say "now disappear", it's impossible. People that work with real economics know that. So one thing is the ideological or political use of this term, "decoupling". Another thing is the real economic meaning of decoupling. In the political arena, you can talk about that. But in practical terms, you can reduce but never decouple.

          中美經濟用了二三十年才達到了今天這種融合程度,現在僅憑一紙總統令就要中止合作,這是不可能的。從事實體經濟的人都明白這點。“脫鉤”在意識形態或政治上,與在實體經濟中,有著不同的含義。在政治方面或許會有這方面的討論,在實際情況中,融合或許會減少,但脫鉤絕不可能發生。

          中國發展的四大因素

          Q:As former special advisor to the president of Brazil, what do you think of China's development?

          作為前巴西總統顧問,你怎么看待中國的發展?

          A:I think the root of China's objective, is to achieve development for its people. It's very important. It's not a dream, it's a reality. And I think China can do that because it has its unique system.

          我認為中國發展目標的根基在于為人民謀發展。這一點非常重要。這不是夢,這是現實。我認為中國可以做到這點,因為它有獨特的體制。

          How can China get to that? I always say that there are some important elements. The first element that’s very critical is leadership. When the leadership takes a decision, that's taken seriously by everybody, by private sector, by media, by government. So you know the direction where you need to go.

          中國如何實現發展?我一直說有幾個重要因素。第一個關鍵因素是領導力。中國的領導層做出決策時,全民都認真參與其中,私有企業、媒體、政府都包括在內,所以你可以清楚了解國家的發展方向。

          The second important element is education. I am doing a research, and I see that at least thirty percent of the income of families go to education. Not only formal education but after school, K12, everything. So that's very important. If you have money, you put money in education and that's different in Western society. Sometimes we take education for granted. We don't think that you need it. Many people say, because the competition in China is huge. But it doesn’t matter if he's in China or outside. You want to prepare. So the second element is education.

          第二個因素,是教育。我在做一項調研,我發現中國家庭收入里,至少三成以上都投入到了教育之中。不僅是正規教育,還有課后輔導,基礎教育等等。這很重要。中國家庭把錢花在教育上,這和西方社會不一樣。西方人往往認為教育是理所當然的,不需要額外投入。很多人會說,這是因為中國的競爭壓力很大。但無論在中國還是在國外,人都會面臨競爭,人們總是希望有所準備。所以第二個因素是教育。

          The third element is the faith that the population has in the government and in the system. The government plays an important role in terms of leadership, but plays a much more important role in terms of governance. So people understand where you want to go.

          第三個因素是中國人對政府和體制的信念。政府發揮著重要的領導決策作用,也發揮著重要的治理職能。所以人們能了解政府的方向。

          The fourth element I think, it's an important element, is the culture of Chinese people, is how they perceive the world. Not in the short run, but it's a long run.

          第四個因素,我認為是很重要的一點,是中國的文化,是中國人民如何看待世界,不是只看眼前,而是長遠規劃。

          I think those four elements are the elements that make China different than any other place around the world.

          在我看來,這四個因素讓中國不同于世界其他地區。

          結語

          Unique systems, solid education, firm faith in the government, and long-term vision are the four characteristics of China's path, in Professor Teixeira's observation. With its roots in Chinese soil, the country's path has proved suitable for China's culture and conditions. It has brought the Chinese people peaceful and fulfilled lives, and the Chinese nation lasting prosperity.

          獨特的體系、扎實的教育、人民對政府的堅定信念以及長遠規劃,是福鑫教授觀察到的中國道路的四大特征。中國道路扎根于中國土壤,實踐證明,它適應中國的文化和國情。它給中國百姓帶來了安穩幸福的生活,也給國家帶來了長富久安。

          出品人:王浩

          監制:柯榮誼 宋平

          制片:張少偉 欒瑞英

          記者:沈一鳴 張欣然 史雪凡周星佐 劉源

          實習生:呂紅梅 錢昕瑀 王博麟劉瑩 孫伊茗 張奕杰

          中國觀察智庫

          中國日報新媒體中心

          聯合出品


          這是一篇很久之前就想動筆寫的文章,最近正好看到群里有小伙伴分享了 Dubbo 連接相關的文章,才又讓我想起了這個話題。今天想跟大家聊的便是 Dubbo 中的連接控制這一話題。說到“連接控制”,可能有讀者還沒反應過來,但你對下面的配置可能不會感到陌生:

          <dubbo:reference interface="com.foo.BarService" connections="10" />
          

          如果你還不了解 Dubbo 中連接控制的用法,可以參考官方文檔:https://dubbo.apache.org/zh/docs/advanced/config-connections/ ,話說最近 Dubbo 官方文檔來了一次大換血,好多熟悉的文檔差點都沒找到在哪兒 Orz。

          眾所周知,dubbo 協議通信默認是長連接,連接配置功能用于決定消費者與提供者建立的長連接數。但官方文檔只給出了該功能的使用方法,卻并沒有說明什么時候應該配置連接控制,本文將主要圍繞該話題進行探討。

          本文也會涉及長連接相關的一些知識點。

          使用方式

          先來看一個 Dubbo 構建的簡單 demo,啟動一個消費者(192.168.4.226)和一個提供者(192.168.4.224),配置他們的直連。

          消費者:

          <dubbo:reference id="userService" check="false"
             interface="org.apache.dubbo.benchmark.service.UserService"
             url="dubbo://192.168.4.224:20880"/>
          

          提供者:

          <dubbo:service interface="org.apache.dubbo.benchmark.service.UserService" ref="userService" />
          <bean id="userService" class="org.apache.dubbo.benchmark.service.UserServiceServerImpl"/>
          

          長連接是看不見摸不著的東西,我們需要一個觀測性工作來”看到“它。啟動提供者和消費者之后,可以使用如下的命令查看 tcp 連接情況

          • Mac 下可使用:lsof -i:20880
          • Linux 下可使用:netstat -ano | grep 20880

          提供者:

          [root ~]# netstat -ano | grep 20880
          tcp6       0      0 192.168.4.224:20880      :::*                    LISTEN      off (0.00/0/0)
          tcp6    2502      0 192.168.4.224:20880      192.168.4.226:59100     ESTABLISHED off (0.00/0/0)
          

          消費者:

          [root@ ~]# netstat -ano | grep 20880
          tcp6     320    720 192.168.4.226:59110     192.168.4.224:20880      ESTABLISHED on (0.00/0/0)
          

          通過上述觀察到的現象我們可以發現幾個事實。

          僅僅是啟動了提供者和消費者,上述的 TCP 連接就已經存在了,要知道我并沒有觸發調用。也就是說,Dubbo 建連的默認策略是在地址發現時,而不是在調用時。當然,你也可以通過延遲加載 lazy="true" 來修改這一行為,這樣可以將建聯延遲到調用時。

          <dubbo:reference id="userService" check="false"
              interface="org.apache.dubbo.benchmark.service.UserService"
              url="dubbo://192.168.4.224:20880"
              lazy="true"/>
          

          除此之外,還可以發現消費者和提供者之間只有一條長連接,20880 是 Dubbo 提供者默認開放的端口,就跟 tomcat 默認開放的 8080 一個地位,而 59110 是消費者隨機生成的一個端口。(我之前跟一些朋友交流過,發現很多人不知道消費者也是需要占用一個端口的)

          而今天的主角”連接控制“便可以控制長連接的數量,例如我們可以進行如下的配置

          <dubbo:reference id="userService" check="false"
              interface="org.apache.dubbo.benchmark.service.UserService"
              url="dubbo://192.168.4.224:20880"
              connections="2" />
          

          再啟動一次消費者,觀察長連接情況

          提供者:

          [root@ ~]# netstat -ano | grep 20880
          tcp6       0      0 192.168.4.224:20880      :::*                    LISTEN      off (0.00/0/0)
          tcp6    2508     96 192.168.4.224:20880      192.168.4.226:59436     ESTABLISHED on (0.00/0/0)
          tcp6    5016    256 192.168.4.224:20880      192.168.4.226:59434     ESTABLISHED on (0.00/0/0)
          

          消費者:

          [root@ ~]# netstat -ano | grep 20880
          tcp6       0   2520 192.168.4.226:59436     192.168.4.224:20880      ESTABLISHED on (0.00/0/0)
          tcp6      48   1680 192.168.4.226:59434     192.168.4.224:20880      ESTABLISHED on (0.00/0/0)
          

          可以看到,這里已經變成兩條長連接了。

          什么時候需要配置多條長連接

          現在我們知道了如何進行連接控制,但什么時候我們應該配置多少條長連接呢?這個時候我可以跟你說,具體視生產情況而定,但你如果你經常看我的公眾號,肯定會知道這不是我的風格,我的風格是什么?benchmark!

          寫作之前,我跟幾個同事和網友對這個話題進行了簡單的討論,其實也沒有什么定論,無非是對單連接和多連接吞吐量高低不同的論調。參考既往 Dubbo github 中的 issue,例如:https://github.com/apache/dubbo/pull/2457,我也參與了這個 pr 的討論,講道理,我是持懷疑態度的,我當時的觀點是多連接不一定能夠提升服務的吞吐量(還是挺保守的,沒有這么絕對)。

          那接下來,還是用 benchmark 來說話吧,測試工程還是我們的老朋友,使用 Dubbo 官方提供的 dubbo-benchmark 工程。

          • 測試工程地址:https://github.com/apache/dubbo-benchmark.git
          • 測試環境:2 臺阿里云 Linux 4c8g ECS

          測試工程在之前的文章介紹過,這里就不過多贅述了,測試方案也非常簡單,兩輪 benchmark,分別測試 connections=1 和 connections=2 時,觀察測試方法的吞吐量。

          說干就干,省略一堆測試步驟,直接給出測試結果。

          connections=1

          Benchmark           Mode  Cnt      Score      Error  Units
          Client.createUser  thrpt    3  22265.286 ± 3060.319  ops/s
          Client.existUser   thrpt    3  33129.331 ± 1488.404  ops/s
          Client.getUser     thrpt    3  19916.133 ± 1745.249  ops/s
          Client.listUser    thrpt    3   3523.905 ±  590.250  ops/s
          

          connections=2

          Benchmark           Mode  Cnt      Score      Error  Units
          Client.createUser  thrpt    3  31111.698 ± 3039.052  ops/s
          Client.existUser   thrpt    3  42449.230 ± 2964.239  ops/s
          Client.getUser     thrpt    3  30647.173 ± 2551.448  ops/s
          Client.listUser    thrpt    3   6581.876 ±  469.831  ops/s
          

          從測試結果來看,似乎單連接和多連接的差距是非常大的,近乎可以看做是 2 倍!看起來連接控制的效果真是好呀,那么事實真的如此嗎?

          按照這種方案第一次測試下來之后,我也不太相信這個結果,因為我之前按照其他方式做過多連接的測試,并且我也參加過第三屆中間件挑戰賽,使得我對長連接的認知是:大多數時候,單連接往往能發揮出最優的性能。即使由于硬件原因,這個差距也不應該是兩倍。懷著這樣的疑問,我開始研究,是不是我的測試場景出了什么問題呢?

          發現測試方案的問題

          經過和閃電俠的討論,他的一席話最終讓我定位到了問題的所在。

          閃電俠的對話

          不知道大家看完我和閃電俠的對話,有沒有立刻定位到問題所在。

          之前測試方案最大的問題便是沒有控制好變量,殊不知:在連接數變化的同時,實際使用的 IO 線程數實際也發生了變化

          Dubbo 使用 Netty 來實現長連接通信,提到長連接和 IO 線程的關系,這里就要介紹到 Netty 的連接模型了。一言以蔽之,Netty 的設置 IO worker 線程和 channel 是一對多的綁定關系,即一個 channel 在建連之后,便會完全由一個 IO 線程來負責全部的 IO 操作。再來看看 Dubbo 是如何設置 NettyClient 和 NettyServer 的 worker 線程組的:

          客戶端 org.apache.dubbo.remoting.transport.netty4.NettyClient

              private static final EventLoopGroup NIO_EVENT_LOOP_GROUP = eventLoopGroup(Constants.DEFAULT_IO_THREADS, "NettyClientWorker");
              
              @Override
              protected void doOpen() throws Throwable {
                  final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);
                  bootstrap = new Bootstrap();
                  bootstrap.group(NIO_EVENT_LOOP_GROUP)
                          .option(ChannelOption.SO_KEEPALIVE, true)
                          .option(ChannelOption.TCP_NODELAY, true)
                          .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
                ...
              }
          

          Constants.DEFAULT_IO_THREADSorg.apache.dubbo.remoting.Constants 中被寫死了

          int DEFAULT_IO_THREADS = Math.min(Runtime.getRuntime().availableProcessors() + 1, 32);
          

          在我的 4c8g 的機器上,默認等于 5。

          服務端 org.apache.dubbo.remoting.transport.netty4.NettyServer

          protected void doOpen() throws Throwable {
                  bootstrap = new ServerBootstrap();
          
                  bossGroup = NettyEventLoopFactory.eventLoopGroup(1, "NettyServerBoss");
                  workerGroup = NettyEventLoopFactory.eventLoopGroup(
                          getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
                          "NettyServerWorker");
          
                  final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);
                  channels = nettyServerHandler.getChannels();
          
                  ServerBootstrap serverBootstrap = bootstrap.group(bossGroup, workerGroup)
                      .channel(NettyEventLoopFactory.serverSocketChannelClass());
                  .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
                          .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
                          .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
                          
           }
          

          服務端倒是可以配置,例如我們可以通過 protocol 來控制服務端的 IO 線程數:

          <dubbo:protocol name="dubbo" host="${server.host}" server="netty4" port="${server.port}" iothreads="5"/>
          

          如果不設置,則跟客戶端邏輯一致,是 core + 1 個線程。

          好了,問題就在這兒,由于我并沒有進行任何 IO 線程的設置,所以客戶端和服務端都會默認開啟 5 個 IO 線程。當 connections=1 時,Netty 會將 channel1 綁定到一個 IO 線程上,而當 connections=2 時,Netty 會將 channel1 和 channel2 按照順序綁定到 NettyWorkerThread-1和 NettyWorkerThread-2 上,這樣就會有兩個 IO 線程在工作,這樣的測試結果當然是不公平的。

          這里需要考慮實際情況,在實際生產中,大多數時候都是分布式場景,連接數一定都是大于 IO 線程數的,所以基本不會出現測試場景中的 channel 數少于 IO 線程數的場景。

          解決方案也很簡單,我們需要控制變量,讓 IO 線程數一致,僅僅觀察連接數對吞吐量的影響。針對服務端,可以在 protocol 層配置 iothreads=1;針對客戶端,由于源碼被寫死了,這里我只能通過修改源碼的方式,重新本地打了一個包,使得客戶端 IO 線程數也可以通過 -D 參數指定。

          改造之后的,我們得到了如下的測試結果:

          1 IO 線程 1 連接

          Benchmark           Mode  Cnt      Score      Error  Units
          Client.createUser  thrpt    3  22265.286 ± 3060.319  ops/s
          Client.existUser   thrpt    3  33129.331 ± 1488.404  ops/s
          Client.getUser     thrpt    3  19916.133 ± 1745.249  ops/s
          Client.listUser    thrpt    3   3523.905 ±  590.250  ops/s
          

          1 IO 線程 2 連接

          Benchmark           Mode  Cnt      Score      Error  Units
          Client.createUser  thrpt    3  21776.436 ± 1888.845  ops/s
          Client.existUser   thrpt    3  31826.320 ± 1350.434  ops/s
          Client.getUser     thrpt    3  19354.470 ±  369.486  ops/s
          Client.listUser    thrpt    3   3506.714 ±   18.924  ops/s
          

          可以發現,單純提升連接數并不會提升服務的吞吐量,這樣的測試結果也更加符合我認知的預期。

          總結

          從上述測試的結果來看,一些配置參數并不是越大就代表了越好,類似的例子我也在多線程寫文件等場景分析過,唯有理論分析+實際測試才能得出值得信服的結論。當然個人的測試,也可能會因為局部性關鍵信息的遺漏,導致誤差,例如,如果我最終沒有發現 IO 線程數和連接數之間的隱性關聯,很容易就得出連接數和吞吐量成正比的錯誤結論了。當然,也不一定就代表本文最終的結論是靠譜的,說不定還是不夠完善的,也歡迎大家留言,提出意見和建議。

          最終回到最初的問題,我們什么時候應該配置 Dubbo 的連接控制呢?按照我個人的經驗,大多數時候,生產環境下連接數是非常多的,你可以挑選一臺線上的主機,通過 netstat -ano| grep 20880| wc -l 來大概統計下,一般是遠超 IO 線程數的,沒必要再多配置成倍的連接數,連接數和吞吐量并不是一個線性增長的關系。

          Dubbo 框架有這個能力和大家真的需要用這個能力完全是兩碼事,我相信大多數讀者應該已經過了技術新鮮感驅動項目的階段了吧?如果有一天你需要控制連接數,去達到一定特殊的用途,你就會真心感嘆,Dubbo 真是強呀,這個擴展點都有。

          Dubbo 的連接控制真的完全沒有用嗎?也不盡然,我的測試場景還是非常有限的,可能在不同硬件上會跑出不一樣的效果,例如我在第三屆中間件性能挑戰賽中,就是用 2 連接跑出了最好的成績,并非單連接。

          最后,你如果僅僅使用 Dubbo 去維系你們的微服務架構,大部分情況不需要關注到連接控制這個特性,多花點時間搬磚吧,就醬,我也去搬磚了。


          主站蜘蛛池模板: 亚洲精品日韩一区二区小说| 精品国产AⅤ一区二区三区4区| 国产在线一区二区三区| 中文字幕亚洲综合精品一区| 国产在线观看精品一区二区三区91| 高清国产精品人妻一区二区| 无码人妻精品一区二区三区不卡| 中文字幕人妻丝袜乱一区三区 | 久久久久久免费一区二区三区| 久久久国产精品无码一区二区三区 | 日韩一区二区三区免费播放| 色狠狠AV一区二区三区| 亚洲一区二区视频在线观看| 蜜臀AV无码一区二区三区| 国产精品毛片一区二区三区| 亚洲国产精品一区二区三区久久| 毛片一区二区三区无码| 亚洲一区电影在线观看| 亚洲电影一区二区三区| 成人无码AV一区二区| 国产精品亚洲产品一区二区三区| 手机福利视频一区二区| 精品黑人一区二区三区| 人妻少妇久久中文字幕一区二区| 国产成人精品无码一区二区三区 | 91在线看片一区国产| 久久久久久综合一区中文字幕 | 国产精品成人一区二区三区| 无码人妻一区二区三区av| 亚洲一区中文字幕| 亚洲一区影音先锋色资源| 免费视频一区二区| 中文字幕色AV一区二区三区| 国产精品一区在线观看你懂的| 秋霞鲁丝片一区二区三区| 精品一区二区三区中文| 国产成人无码aa精品一区| 在线电影一区二区三区| 97久久精品无码一区二区| 国产一区二区三区韩国女主播| 亚洲一区二区三区播放在线|