HTML躬行記(1)——SVG

  <svg>是矢量圖的根元素,通過xmlns屬性聲明命名空間,從而告訴用戶代理標記名稱屬於哪個XML方言。在下面的示例中,為<svg>元素聲明了寬度和高度(默認以像素為單位),其子元素<title>可作為提示,在<desc>中可聲明一段描述性純文本,這兩個元素都不會在頁面中呈現。而<rect>是一個矩形,將被繪製到頁面中。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <title>SVG example</title>
  <desc>SVG contains a rectangle</desc>
  <rect width="50" height="50" fill="#F60" />
</svg>

  SVG作為一種圖像格式,可以包含在<img>元素內(如下所示)或CSS樣式中(例如background-image屬性)。

<img src="demo.svg" />

一、坐標系統

1)視口

  在SVG中,有一張無限大的畫布,而畫布區域被稱為視口(viewport)。通過<svg>元素的width和height兩個屬性可定義視口的尺寸,視口的原點在其左上角。

  而在視口中,還包含一個坐標系統,由viewBox屬性控制。它能包含四個數值(以逗號或空格分隔),分別是用戶坐標系統的最小橫坐標(x軸)和縱坐標(y軸),以及寬和高。

  下面的兩個<svg>元素,第一個採用了默認的坐標系統,第二個聲明了新的坐標系統,並且寬高比相同,如圖1所示,第二個矩形縮小了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>

圖 1

  接下來修改兩個最小坐標(如圖2所示),第一個<svg>元素聲明的最小坐標為(20,20),雖然矩形的坐標是(0,0),但是比最小坐標要小,所以就會往左上角偏移;第二個<svg>元素聲明了負數坐標,與前一個正好相反;在第三個<svg>元素中,修改了矩形的坐標,正好在左上角。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="-20 -20 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
  <rect width="50" height="50" fill="#F60" x="20" y="20" />
</svg>

圖 2

2)preserveAspectRatio屬性

  當viewBox屬性中聲明的尺寸與視圖的寬高比不一致時,可以使用preserveAspectRatio屬性指定圖形的縮放比例和對齊方式,語法如下,默認值是“xMidYMid meet”。

preserveAspectRatio: <align> [<meetOrSlice>]

  其中<align>的屬性值由兩個軸(x和y)以及三個位置(min、mid和max)組合而成,如表1所列。

表 1

值 說明
xMin viewport與viewBox的左側對齊
xMid viewport與viewBox的x軸中點對齊
xMax viewport與viewBox的右側對齊
YMin viewport與viewBox的頂部對齊
YMid viewport與viewBox的y軸中點對齊
YMax viewport與viewBox的底部對齊

  在下面的示例中,由於三個<svg>元素寬高比是3:2,而viewBox的寬高比是3:1,因此矩形會等比縮小。對它們分別應用xMinYMin、xMidYMid和xMinYMax,效果如圖3所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMidYMid">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMax">
  <rect width="50" height="50" fill="#F60" />
</svg>

圖 3

  注意,因為寬度正好適配,所以對於x軸的對齊方式,效果都是相同的。

  <meetOrSlice>可控製圖形的適配或裁剪,可選的值如表2所列。

表 2

值 說明
meet 保留圖形的寬高比,並且縮放viewBox以適應viewport
slice 保留圖形的寬高比,並且放大viewBox以覆蓋viewport

  在下面的示例中,兩個矩形的高度比視口要大,對它們分別應用meet和slice,效果如圖4所示,第二個矩形將整個視口給填滿了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin meet">
  <rect width="150" height="150" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin slice">
  <rect width="150" height="150" fill="#F60" />
</svg>

圖 4

二、形狀

  SVG的基本形狀包括線段(line)、矩形(rect)、圓形(circle)、橢圓(ellipse)、多邊形(polygon)和折線(polyline)。

1)<line>

  線段元素需要指定起止點的坐標,如下所示,效果如圖5所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <line x1="20" y1="100"  x2="100" y2="20" stroke="black" stroke-width="2"/>
</svg>

圖 5

  其中stroke和stroke-width是筆畫屬性,可指定筆畫的顏色和寬度,相關屬性如表3所列,部分屬性的效果如圖6所示。

表 3

值 說明
stroke 筆畫顏色
stroke-dasharray 筆畫的外觀(實線、點線或虛線),由一系列逗號分隔的数字組成,表示長度和空隙長度
stroke-dashoffset 相對繪圖起點的偏移值
stroke-linecap 描邊的展現形狀
stroke-linejoin 路徑轉角處的形狀
stroke-miterlimit 斜接長度與線寬的最大比例
stroke-opacity 筆畫不透明度,取值範圍0~1,其中0表示透明
stroke-width 筆畫寬度

圖 6

2)<rect>

  除了直角矩形之外,還可以聲明圓角矩形,如下所示,效果如圖7所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect x="10" y="10" width="100" height="100" rx="15" ry="15" fill="#F60"/>
</svg>

圖 7

3)<circle>和<ellipse>

  利用圓形,可非常便捷的畫出圓環,效果如圖8所示。將<circle>元素的stroke-dasharray聲明為圓的周長(2πR),例如半徑為50,周長就是314。如果為stroke-dashoffset屬性定義一個值,就能得到圓環缺失一段的效果,從而就能模擬出圓環型的進度條了。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <circle cx="100" cy="100" r="50" stroke="black" stroke-width="2" 
    stroke-dasharray="314" stroke-dashoffset="40" fill="transparent" />
</svg>

圖 8

  橢圓和圓形類似,只是需要聲明兩個方向的半徑,如圖9所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <ellipse cx="100" cy="100" rx="100" ry="50" />
</svg>

圖 9

4)<polygon>

  <polygon>可畫出任意形狀的封閉圖形,例如平行四邊形、梯形等。在points屬性中,可聲明各個點的坐標,每組坐標用逗號隔開,下面繪製了一個五角星,如圖10所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <polygon points="100,0 160,180 10,60 190,60 40,180" fill="#F60"/>
</svg>

圖 10

5)<polyline>

  折線不需要閉合,與<polygon>元素類似,也是由points屬性繪製,如下所示,得到的折線如圖11所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <polyline points="20,100 40,60 70,80 100,20" fill="none" stroke="black" />
</svg>

圖 11

6)<path>

  上述基本形狀都可以由<path>元素來繪製,並且通過<path>元素還可繪製出不規則的圖形,例如心形,如下所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <path d="M 10,30
           A 20,20 0,0,1 50,30
           A 20,20 0,0,1 90,30
           Q 90,60 50,90
           Q 10,60 10,30 z" />
</svg>

  其中d屬性可聲明一系列路徑,包含多個指令,如表4所列。

表 4

指令 效果
M、m 移動到指定的坐標
L、l 繪製一條直線
H、h 繪製一條水平線
V、v 繪製一條垂直線
Z、z 關閉路徑
Q、q 繪製一條二次貝塞爾曲線
T、t 繪製一條平滑的二次貝塞爾曲線
C、c 繪製一條三次貝塞爾曲線
S、s 繪製一條平滑的三次貝塞爾曲線
A、a 繪製弧形曲線

三、文檔結構

1)內部樣式

  SVG允許在其內部嵌入<style>元素,如下所示,其中CDATA區段中的文本會被解析器忽略,但不影響渲染。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <style>
    <![CDATA[
    line {
      stroke: black;
      stroke-width: 2;
    }
    ]]>
  </style>
  <line x1="20" y1="100" x2="100" y2="20" />
</svg>

2)<g>

  <g>元素相當於一個容器,能將其所有的子元素組合在一起。應用於<g>元素中的屬性會被其子元素所繼承,如下所示,兩個圓的筆畫顏色都是綠色,而寬度都是10,如圖12所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <g id="ring" fill="white" stroke="green" stroke-width="10">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </g>
</svg>

圖 12

3)<use>

  <use>元素可引用其它圖形,以及<g>元素,類似於複製黏貼的功能。在下面的示例中,通過<use>元素的xlink:href屬性引用了id為ring的<g>元素,並且將<use>元素上聲明的屬性傳給了<circle>元素。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <g id="ring">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </g>
  <use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

  注意,當給<use>元素定義坐標后,<circle>元素會與其相加計算出最終的坐標,如圖13所示。

圖 13

4)<defs>

  可將需要復用的圖形抽象到<defs>元素中,在其內部定義的圖形不會直接呈現到頁面中。在上面那個示例的基礎上,將<g>元素整個放置到<defs>中,效果如圖14所示,沒有渲染<g>元素中的圓。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <defs>
    <g id="ring">
      <circle cx="80" cy="80" r="50" />
      <circle cx="120" cy="120" r="50" />
    </g>
  </defs>
  <use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

圖 14

5)<symbol>

  <symbol>提供了另一種組合圖形的方式,但與<g>元素不同,它的圖形不會呈現,並且它可以聲明viewBox和preserveAspectRatio兩個屬性,如下所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
  <symbol id="ring" viewBox="0 0 300 200">
    <circle cx="80" cy="80" r="50" />
    <circle cx="120" cy="120" r="50" />
  </symbol>
  <use fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>

6)<image>

  <use>元素可以引用SVG文件的某個部分,而<image>元素可以引用整個SVG文件或柵格圖像(如下所示),並且能控制引用文件的尺寸和preserveAspectRatio屬性,效果如圖15所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <image xlink:href="img/avatar.png" width="150" />
</svg>

圖 15

四、變形、圖案和漸變

1)變形

  transform屬性定義了一系列圖形元素變形的規則,包括位移(translate)、縮放(scale)、旋轉(rotate)和傾斜(skew)。注意,與CSS3中的transform屬性不同,SVG中的transform屬性作用的對象是坐標系統,而不是元素本身。

  translate()函數會接收兩個參數,沿x軸和y軸位移坐標系統,如圖16所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="translate(50, 30)" />
</svg>

圖 16

  scale()函數也會接收兩個參數(這點與CSS3中的scale()不同),沿x軸和y軸縮放坐標系統,如圖17所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="scale(2, 3)" />
</svg>

圖 17

  rotate()函數可接收三個參數,第一個是旋轉角度,另外兩個是原點坐標,也就是坐標系統按照該原點旋轉,如圖18所示,第三個矩形指定了原點。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="rotate(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="rotate(30, 50, 30)" />
</svg>

圖 18

  傾斜分為兩個函數:skewX()和skewY(),分別會沿着x軸和y軸傾斜,如圖19所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="skewX(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
  <rect width="50" height="50" fill="#F60" transform="skewY(30)" />
</svg>

圖 19

2)圖案

  要創建一個圖案,就得使用<pattern>元素包裹圖形元素,再利用patternUnits屬性確定平鋪圖案的方式。它有兩個關鍵字可選,默認的objectBoundingBox會讓<pattern>元素的尺寸以百分數或0~1之間的小數表示,參照對象分別是引用<pattern>的圖形元素的寬和高。

  以下面的圖案為例,它的寬和高都是10%,參照的圓形的寬高都是200,計算出的實際值就都是20,效果如圖20所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star1" width="10%" height="10%" patternUnits="objectBoundingBox">
      <circle cx="10" cy="10" r="10" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star1)" />
</svg>

圖 20

  另一個userSpaceOnUse會讓<pattern>元素的尺寸以絕對值表示,如下所示,因為<pattern>元素的寬高都為25,所以圖案會有空白間隙,得到的效果如圖21所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star2" width="25" height="25" patternUnits="userSpaceOnUse">
      <circle cx="10" cy="10" r="10" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star2)" />
</svg>

圖 21

  <pattern>元素還包含另一個patternContentUnits屬性,用於處理圖案內部的排列方式,它的兩個關鍵字也是objectBoundingBox和userSpaceOnUse,後者是該屬性的默認值。

  objectBoundingBox會讓<pattern>中的圖形元素以小數定義,如下所示。三個屬性值都是0.1(不能用百分數),參照的仍然是引用<pattern>的圖形元素,計算得到的實際值都是20,效果如圖22所示,每個圖案只显示四分之一個圓。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <pattern id="star3" width="10%" height="10%" patternContentUnits="objectBoundingBox">
      <circle cx=".1" cy=".1" r=".1" />
    </pattern>
  </defs>
  <circle cx="100" cy="100" r="100" fill="url(#star3)" />
</svg>

圖 22

3)漸變

  <linearGradient>元素用於繪製線性漸變,其子元素<stop>可指定某處的色標(即漸變點),如下所示,在起點、中點和止點處聲明了三種顏色,其中stop-opacity用於聲明不透明度(取值範圍0~1),1表示完全不透明,得到的效果如圖23所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="#F60" />
      <stop offset="50%" stop-color="#CCC" stop-opacity=".5"/>
      <stop offset="100%" stop-color="#FC0" />
    </linearGradient>
  </defs>
  <rect width="200" height="100" fill="url(#gradient)" />
</svg>

圖 23

  如果要改變線性漸變的方向,可通過修改起點和終點的坐標實現,例如沿垂直線漸變,代碼如下,得到的效果如圖24所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <defs>
    <linearGradient id="gradientVertical" x1="0" y1="0" x2="0" y2="100%">
      <stop offset="0" stop-color="#F60" />
      <stop offset="50%" stop-color="#CCC" stop-opacity=".5" />
      <stop offset="100%" stop-color="#FC0" />
    </linearGradient>
  </defs>
  <rect width="200" height="100" fill="url(#gradientVertical)" />
</svg>

圖 24

  <linearGradient>元素還有一個spreadMethod屬性,可指定在漸變範圍之外的填充方式,它有三個值可選,如下所列。

  (1)pad:默認值,用起點和終點的顏色填充。

  (2)reflect:按終點到起點,起點到終點的方式重複填充。

  (3)repeat:按起點到終點的方式重複填充。

  下面用一個示例來演示spreadMethod屬性,如圖25所示,從左往右,spreadMethod屬性的值依次是pad、reflect和repeat。

<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200">
  <defs>
    <linearGradient id="spreadMethod" x1="20%" y1="30%" x2="60%" y2="70%">
      <stop offset="0" stop-color="#F60" />
      <stop offset="40%" stop-color="#CCC" />
      <stop offset="80%" stop-color="#FC0" />
    </linearGradient>
    <linearGradient id="gradientPad" href="#spreadMethod" spreadMethod="pad" />
    <linearGradient id="gradientReflect" href="#spreadMethod" spreadMethod="reflect" />
    <linearGradient id="gradientRepeat" href="#spreadMethod" spreadMethod="repeat" />
  </defs>
  <rect width="200" height="100" fill="url(#gradientPad)" />
  <rect width="200" height="100" fill="url(#gradientReflect)" x="210" />
  <rect width="200" height="100" fill="url(#gradientRepeat)" x="420" />
</svg>

圖 25

  另外一種徑向漸變由<radialGradient>元素控制,具體可參考官方文檔。

五、文本

1)<text>

  <text>元素用於處理SVG文件中的文本,在該元素中可修改字體樣式,包括字體名稱、大小、顏色、外觀等。在下面的示例中,聲明了四個<text>元素,併為它們添加了各自的樣式,效果如圖26所示。

<svg xmlns="http://www.w3.org/2000/svg" width="250" height="100">
  <style>
    .small {
      font: italic 13px sans-serif;
    }
    .heavy {
      font: bold 30px sans-serif;
    }
    .Rrrrr {
      font: italic 40px serif;
      fill: red;
    }
  </style>
  <text x="20" y="35" class="small">My</text>
  <text x="40" y="35" class="heavy">name</text>
  <text x="55" y="55" class="small">is</text>
  <text x="65" y="55" class="Rrrrr">Strick!</text>
</svg>

圖 26

2)對齊

  在<text>元素中對齊文本得用text-anchor屬性,它的對齊方式為起點(start)、居中(middle)和終點(end)。在下面的示例中,為了便於觀察這三個關鍵字的行為,畫了一條參考線,如圖27所示。

<svg xmlns="http://www.w3.org/2000/svg" width="120" height="150">
  <path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
  <text text-anchor="start" x="60" y="40">Start</text>
  <text text-anchor="middle" x="60" y="75">Middle</text>
  <text text-anchor="end" x="60" y="110">End</text>
</svg>

圖 27

  SVG中的文本對齊與CSS中的略有不同,當起點對齊時,第一個字符會貼着參考線;當居中對齊時,文本的中間位置會被參考線貫穿;當終點對齊時,文本的最後一個字符會貼着參考線。

3)<tspan>

  在<text>元素中,通過其子元素<tspan>可調整文本屬性,從而實現一段文本呈現不同的效果,如下所示,這段文本為斜體,而<tspan>元素中的文本被加粗並且賦予了紅色(如圖28所示)。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <style>
    text {
      font: italic 18px serif;
    }
    tspan {
      font: bold 20px sans-serif;
      fill: red;
    }
  </style>
  <text x="10" y="30" class="small">
    My name is
    <tspan>Strick</tspan>!
  </text>
</svg>

圖 28

4)長度
  textLength屬性用於定義文本的長度,lengthAdjust屬性用於設置字符間距和字形,如下所示,默認值spacing只會控制字符間距,而spacingAndGlyphs還能控制字形,如圖29所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="60">
  <text y="20" textLength="90%" lengthAdjust="spacing">Big text length</text>
  <text y="40" textLength="90%" lengthAdjust="spacingAndGlyphs">Big text length</text>
</svg>

圖 29

5)文本路徑

  將文本放置在<textPath>元素中,就可讓文本按任意的路徑排列,而不是以往的水平或垂直排列。在下面的示例中,文本按一條螺旋曲線排列,如圖30所示。

<svg xmlns="http://www.w3.org/2000/svg" width="150" height="120">
  <defs>
    <path id="curve" d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50" />
  </defs>
  <text>
    <textPath href="#curve">
      My name is Strick! What is your name?
    </textPath>
  </text>
</svg>

圖 30

六、動畫

1)<animate>

  <animate>是一個動畫元素,它可以包含在圖形元素中,多個<animate>元素可以實現多重動畫。例如將矩形先沿着水平方向,再沿着垂直方向位移,最後在位移結束后切換背景色的動畫,代碼如下所示,效果如圖31。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <rect id="move" width="50" height="50" fill="#F60">
    <animate attributeType="XML" dur="1s" repeatCount="1" attributeName="x"
        from="0" to="50" fill="freeze" begin="1s" id="line" />
    <animate attributeType="XML" dur="1s" repeatCount="1" attributeName="y"
        from="0" to="30" fill="freeze" begin="2s" />
    <animate attributeType="XML" dur="3s" repeatCount="indefinite" attributeName="fill"
        values="#F60;#FC0;#CCC" begin="line.end" />
  </rect>
</svg>

圖 31

  <animate>元素包含多個動畫屬性,此處只使用了其中的幾個,具體說明如下,其中fill=”freeze”是指動畫結束后保持最後的動作。

  (1)attributeName:執行動畫的屬性。

  (2)attributeType:屬性類型,可選值包括XML和CSS。

  (3)from:屬性的起始值。

  (4)to:屬性的結束值。

  (5)dur:動畫持續時間。

  (6)repeatCount:動畫執行次數,可以是有限次的整數,也可以是無限次的indefinite。

  (7)begin:動畫開始時機,可以是秒數,也可以是某個動作,例如上面第一個動畫結束后執行顏色的切換。

  <set>元素是對<animate>元素的補充,可為那些不能過渡的屬性提供動畫,例如在某個時刻显示文本,如下所示,點擊矩形可显示“change color”。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <!--省略矩形代碼-->
  <text x="100" y="20" text-anchor="middle" style="display:none">
    <set attributeName="display" attributeType="CSS" to="block" begin="move.click" dur="1s" fill="freeze" />
    change color
  </text>
</svg>

2)<animateTransform>

  對於transform屬性的動畫,得用<animateTransform>元素完成。下面的示例演示了旋轉矩形(如圖32所示),其中type屬性用於指定變形的動作,可選的值有translate、scale、rotate、skewX和skewY。

<svg xmlns="http://www.w3.org/2000/svg" width="180" height="160">
  <rect id="move" width="50" height="50" fill="#F60" x="80" y="80">
    <animateTransform attributeName="transform" attributeType="XML" type="rotate"
        from="0 80 80" to="360 80 80" dur="5s" repeatCount="indefinite" />
  </rect>
</svg>

圖 32

3)<animateMotion>

  <animateMotion>元素可讓圖形沿着任意路徑運動,無論是直線還是曲線,都能實現。在下面的示例中,橙色矩形會沿着S型曲線來回運動,如圖33所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <path fill="none" stroke="#000"
        d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  <rect width="20" height="10" fill="#F60">
    <animateMotion dur="10s" repeatCount="indefinite"
        path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  </rect>
</svg>

圖 33

  如果要讓矩形始終沿着平行於曲線的方向運動,那麼可以將rotate屬性設為auto,如圖34所示。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
  <path fill="none" stroke="#000"
        d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  <rect width="20" height="10" fill="#F60">
    <animateMotion dur="10s" repeatCount="indefinite" rotate="auto"
        path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
  </rect>
</svg>

圖 34

 

【參考資料】
SVG元素參考

[技術分享] 理解 SVG 中的 Viewport 和 ViewBox-拖曳與縮放功能實做(上)

理解SVG viewport,viewBox,preserveAspectRatio縮放

SVG圖像的viewport和viewBox用於設置圖像可見區域的大小

SVG:理解stroke-dasharray和stroke-dashoffset屬性

SVG 研究之路 (16) – Stroke-miterlimit

如何使用SVG圖案

SVG 研究之路 (26) – 有趣的 Patterns

 

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

上周熱點回顧(6.15-6.21)

熱點隨筆:

· 因為知道了30+款在線工具,我的工作效率提升500%! (HollisChuang)
· 什麼?一個核同時執行兩個線程? (軒轅之風)
· .Net微服務實戰之DevOps篇 (陳珙)
· .Net 對於PDF生成以及各種轉換的操作 (沉_默)
· 龍芯團隊完成CoreCLR MIPS64移植,已在github開源 (張善友)
· foreach 集合又拋經典異常了,這次一定要刨根問底 (一線碼農)
· 對 JsonConvert 的認識太膚淺了,終於還是遇到了問題 (一線碼農)
· 深入理解 EF Core:EF Core 讀取數據時發生了什麼? (LiamWang)
· 養生吧,程序員! (沉默王二)
· cute-cnblogs 自定義博客園樣式美化二期來啦~ (麋鹿魯喲)
· .Net Core基礎的健康檢查 (她微笑的臉)
· 代碼之間為什麼要加空格? (沉默王二)

熱點新聞:

· 字節跳動程序員期權價值過億 28歲辭職享受人生引熱議 當事人回應
· 阿里P8員工1.6w招私人助理,網友群嘲:你咋不上天呢?
· 我,掉進20萬創業補貼陷阱:最後被告上法庭
· 獨家專訪28歲退休程序員郭宇:1600人加好友,問我“掙了多少錢”
· 北斗導航系統最後一顆衛星就緒:後天發射!
· 有碼變高清!AI一秒還原馬賽克,杜克大學出品
· “零收入”依然淡定,一家基礎軟件公司的冒險與底氣
· 重磅!突破美國封鎖,國產操作系統“天賜”即將誕生,火爆知乎
· 充電器1萬一隻53萬!波士頓動力網紅機器狗開售
· AMD將改寫10年來DIY市場歷史:份額逼近30% 大廠全齊了
· 兩千元的「反 5G 量子設備」,到底是怎樣的智商稅?
· 自主研發 華米發布全球最強大可穿戴人體傳感器

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

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

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

Linux上TCP的幾個內核參數調優

Linux作為一個強大的操作系統,提供了一系列內核參數供我們進行調優。光TCP的調優參數就有50多個。在和線上問題鬥智斗勇的過程中,筆者積累了一些在內網環境應該進行調優的參數。在此分享出來,希望對大家有所幫助。

調優清單

好了,在這裏先列出調優清單。請記住,這裏只是筆者在內網進行TCP內核參數調優的經驗,僅供參考。同時,筆者還會在餘下的博客裏面詳細解釋了為什麼要進行這些調優!

序號 內核參數 值 備註
1.1 /proc/sys/net/ipv4/tcp_max_syn_backlog 2048
1.2 /proc/sys/net/core/somaxconn 2048
1.3 /proc/sys/net/ipv4/tcp_abort_on_overflow 1
2.1 /proc/sys/net/ipv4/tcp_tw_recycle 0 NAT環境必須為0
2.2 /proc/sys/net/ipv4/tcp_tw_reuse 1
3.1 /proc/sys/net/ipv4/tcp_syn_retries 3
3.2 /proc/sys/net/ipv4/tcp_retries2 5
3.3 /proc/sys/net/ipv4/tcp_slow_start_after_idle 0

tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow

tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow這三個參數是關於
內核TCP連接緩衝隊列的設置。如果應用層來不及將已經三次握手建立成功的TCP連接從隊列中取出,溢出了這個緩衝隊列(全連接隊列)之後就會丟棄這個連接。如下圖所示:

從而產生一些詭異的現象,這個現象詭異之處就在於,是在TCP第三次握手的時候丟棄連接

就如圖中所示,第二次握手的SYNACK發送給client端了。所以就會出現client端認為連接成功,而Server端確已經丟棄了這個連接的現象!由於無法感知到Server已經丟棄了連接。
所以如果沒有心跳的話,只有在發出第一個請求后,Server才會發送一個reset端通知這個連接已經被丟棄了,建立連接后第二天再用,也會報錯!所以我們要調大Backlog隊列!

echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo 2048 > /proc/sys/net/core/somaxconn

當然了,為了盡量避免第一筆調用失敗問題,我們也同時要設置

echo 1 > /proc/sys/net/ipv4/tcp_abort_on_overflow

設置這個值以後,Server端內核就會在這個連接被溢出之後發送一個reset包給client端。

如果我們的client端是NIO的話,就可以收到一個socket close的事件以感知到連接被關閉!

注意Java默認的Backlog是50

這個TCP Backlog的隊列大小值是min(tcp_max_syn_backlog,somaxconn,應用層設置的backlog),而Java如果不做額外設置,Backlog默認值僅僅只有50。C語言在使用listen調用的時候需要傳進Backlog參數。

tcp_tw_recycle

tcp_tw_recycle這個參數一般是用來抑制TIME_WAIT數量的,但是它有一個副作用。即在tcp_timestamps開啟(Linux默認開啟),tcp_tw_recycle會經常導致下面這種現象。

也即,如果你的Server開啟了tcp_tw_recycle,那麼別人如果通過NAT之類的調用你的Server的話,NAT後面的機器只有一台機器能正常工作,其它情況大概率失敗。具體原因呢由下圖所示:

在tcp_tw_recycle=1同時tcp_timestamps(默認開啟的情況下),對同一個IP的連接會做這樣的限制,也即之前後建立的連接的時間戳必須要大於之前建立連接的最後時間戳,但是經過NAT的一個IP後面是不同的機器,時間戳相差極大,就會導致內核直接丟棄時間戳較低的連接的現象。由於這個參數導致的問題,高版本內核已經去掉了這個參數。如果考慮TIME_WAIT問題,可以考慮設置一下

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

tcp_syn_retries

這個參數值得是client發送SYN如果server端不回復的話,重傳SYN的次數。對我們的直接影響呢就是connet建立連接時的超時時間。當然Java通過一些C原生系統調用的組合使得我們可以進行超時時間的設置。在Linux裏面默認設置是5,下面給出建議值3和默認值5之間的超時時間。

tcp_syn_retries timeout
1 min(so_sndtimeo,3s)
2 min(so_sndtimeo,7s)
3 min(so_sndtimeo,15s)
4 min(so_sndtimeo,31s)
5 min(so_sndtimeo,63s)

下圖給出了,重傳和超時情況的對應圖:

當然了,不同內核版本的超時時間可能不一樣,因為初始RTO在內核小版本間都會有細微的變化。所以,有時候在抓包時候可能會出現(3,6,12……)這樣的序列。當然Java的API有超時時間:

java:
 // 函數調用中攜帶有超時時間
 public void connect(SocketAddress endpoint, int timeout) ;

所以,對於Java而言,這個內核參數的設置沒有那麼重要。但是,有些代碼可能會有忘了設置timeout的情況,例如某個版本的Kafka就是,所以它在我們一些混沌測試的情況下,容災恢復的時間會達到一分多鍾,主要時間就是卡在connect上面-_-!,而這時我們的tcp_syn_retries設置的是5,也即超時時間63s。減少這個恢復時間的手段就是:

echo 3 > /proc/sys/net/ipv4/tcp_syn_retries

tcp_retries2

tcp_retries2這個參數表面意思是在傳輸過程中tcp的重傳次數。但在某個版本之後Linux內核僅僅用這個tcp_retries2來計算超時時間,在這段時間的重傳次數純粹由RTO等環境因素決定,重傳超時時間在5/15下的表現為:

tcp_retries2 對端無響應
5 25.6s-51.2s根據動態rto定
15 924.6s-1044.6s根據動態rto定

如果我們在應用層設置的Socket所有ReadTimeout都很小的話(例如3s),這個內核參數調整是沒有必要的。但是,筆者經常發現有的系統,因為一兩個慢的接口或者SQL,所以將ReadTimeout設的很大的情況。

平常這種情況是沒有問題的,因為慢請求頻率很低,不會對系統造成什麼風險。但是,物理機突然宕機時候的情況就不一樣了,由於ReadTimeOut設置的過大,導致所有落到這台宕機的機器都會在min(ReadTimeOut,(924.6s-1044.6s)(Linux默認tcp_retries2是15))后才能從read系統調用返回。假設ReadTimeout設置了個5min,系統總線程數是200,那麼只要5min內有200個請求落到宕機的server就會使A系統失去響應!

但如果將tcp_retries2設置為5,那麼超時返回時間即為min(ReadTimeOut 5min,25.6-51.2s),也就是30s左右,極大的緩解了這一情況。

echo 5 > /proc/sys/net/ipv4/tcp_retries2

但是針對這種現象,最好要做資源上的隔離,例如線程上的隔離或者機器級的隔離。

golang的goroutine調度模型就可以很好的解決線程資源不夠的問題,但缺點是goroutine裏面不能有阻塞的系統調用,不然也會和上面一樣,但僅僅對於系統之間互相調用而言,都是非阻塞IO,所以golang做微服務還是非常Nice的。當然了我大Java用純IO事件觸發編寫代碼也不會有問題,就是對心智負擔太高-_-!

物理機突然宕機和進程宕不一樣

值得注意的是,物理機宕機和進程宕但內核還存在表現完全不一樣。

僅僅進程宕而內核存活,那麼內核會立馬發送reset給對端,從而不會卡住A系統的線程資源。

tcp_slow_start_after_idle

還有一個可能需要調整的參數是tcp_slow_start_after_idle,Linux默認是1,即開啟狀態。開啟這個參數后,我們的TCP擁塞窗口會在一個RTO時間空閑之後重置為初始擁塞窗口(CWND)大小,這無疑大幅的減少了長連接的優勢。對應Linux源碼為:

static void tcp_event_data_sent(struct tcp_sock *tp,
				struct sk_buff *skb, struct sock *sk){
	// 如果開啟了start_after_idle,而且這次發送的時間-上次發送的時間>一個rto,就重置tcp擁塞窗口
	if (sysctl_tcp_slow_start_after_idle &&
	    (!tp->packets_out && (s32)(now - tp->lsndtime) > icsk->icsk_rto))
		tcp_cwnd_restart(sk, __sk_dst_get(sk));
}

關閉這個參數后,無疑會提高某些請求的傳輸速度(在帶寬夠的情況下)。

echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle

當然了,Linux啟用這個參數也是有理由的,如果我們的網絡情況是時刻在變化的,例如拿個手機到處移動,那麼將擁塞窗口重置確實是個不錯的選項。但是就我們內網系統間調用而言,是不太必要的了。

初始CWND大小

毫無疑問,新建連接之後的初始TCP擁塞窗口大小也直接影響到我們的請求速率。在Linux2.6.32源碼中,其初始擁塞窗口是(2-4個)mss大小,對應於內網估計也就是(2.8-5.6K)(MTU 1500),這個大小對於某些大請求可能有點捉襟見肘。
在Linux 2.6.39以上或者某些RedHat維護的小版本中已經把CWND
增大到RFC 6928所規定的的10段,也就是在內網裡面估計14K左右(MTU 1500)。

Linux 新版本
/* TCP initial congestion window */
#define TCP_INIT_CWND		10

公眾號

關注筆者公眾號,獲取更多乾貨文章

總結

Linux提供了一大堆內參參數供我們進行調優,其默認設置的參數在很多情況下並不是最佳實踐,所以我們需要潛心研究,找到最適合當前環境的組合。

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

最通俗易懂的RSA加密解密指導

前言

RSA加密算法是一種非對稱加密算法,簡單來說,就是加密時使用一個鑰匙,解密時使用另一個鑰匙。

因為加密的鑰匙是公開的,所又稱公鑰,解密的鑰匙是不公開的,所以稱為私鑰。

密鑰

關於RSA加密有很多文章,但幾乎都只介紹了RSACryptoServiceProvider類的使用方法,如果只是走走看看,是沒問題的,但真的想使用時,就會發現,你沒有密鑰字符串。。。

下面我們從獲取密鑰字符串開始逐步學習加密。

密鑰字符串

每個安裝過VisualStudio的電腦都可以找到一個文件—makecert.exe。

我電腦的makecert.exe地址:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert.exe

makecert.exe是用來生成證書的程序,我們可以借用該程序來獲取密鑰字符串。

 

編寫生成證書的CreateCertWithPrivateKey函數,代碼如下:

 public static bool CreateCertWithPrivateKey(string subjectName, string makecertPath)
 {
     subjectName = "CN=" + subjectName;
     string param = " -pe -ss my -n \"" + subjectName + "\" ";
     try
     {
         Process p = Process.Start(makecertPath, param);
         p.WaitForExit();
         p.Close();
     }
     catch (Exception e)
     { 
         return false;
     }
     return true;
 }

調用證書生成函數,代碼如下:

string keyName = "Kiba518.Licence";//證書的KEY 
var ret = DataCertificate.CreateCertWithPrivateKey(keyName, @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert.exe");

剛剛生成的證書還存儲在WINDOWS的證書存儲區,現在我們通過證書的Key在證書存儲區查找到證書,並將其到出(導出時需要指定密碼),導出函數代碼如下:

public static bool ExportToPfxFile(string subjectName, string pfxFileName,
    string password, bool isDelFromStore)
{
    subjectName = "CN=" + subjectName;
    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadWrite);
    X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
    foreach (X509Certificate2 x509 in storecollection)
    {
        if (x509.Subject == subjectName)
        { 
            byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
            using (FileStream fileStream = new FileStream(pfxFileName, FileMode.Create))
            {
                // Write the data to the file, byte by byte. 
                for (int i = 0; i < pfxByte.Length; i++)
                    fileStream.WriteByte(pfxByte[i]);
                // Set the stream position to the beginning of the file. 
                fileStream.Seek(0, SeekOrigin.Begin);
                // Read and verify the data. 
                for (int i = 0; i < fileStream.Length; i++)
                {
                    if (pfxByte[i] != fileStream.ReadByte())
                    { 
                        fileStream.Close();
                        return false;
                    }
                }
                fileStream.Close();
            }
            if (isDelFromStore == true)
                store.Remove(x509);
        }
    }
    store.Close();
    store = null;
    storecollection = null;
    return true;
}

調用導出函數,代碼如下:

DataCertificate.ExportToPfxFile(keyName, "Kiba518.pfx", "123456", true);

運行完導出函數后,我們打開Debug文件夾,可以看到證書已經被成功導出了,如下圖:

證書導出后,我們就可以通過讀取證書的信息,來獲取到公鑰和私鑰了。

X509Certificate2 x509 = X509Certificate2("Kiba518.pfx", "123456", X509KeyStorageFlags.Exportable);
string publickey = x509.PublicKey.Key.ToXmlString(false);//公鑰獲取
string privatekey = x509.PrivateKey.ToXmlString(true);//私鑰獲取

公鑰私鑰如下圖所示:

加密解密

得到密鑰字符串后,我們創建RSA的加密解密函數,代碼如下:

//加密
public static string RSADecrypt(string xmlPrivateKey, string enptStr)
{
    RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
    provider.FromXmlString(xmlPrivateKey);
    byte[] rgb = Convert.FromBase64String(enptStr);
    byte[] bytes = provider.Decrypt(rgb, RSAEncryptionPadding.OaepSHA1);
    return new UnicodeEncoding().GetString(bytes);
}
//解密
public static string RSAEncrypt(string xmlPublicKey, string enptStr)
{
    RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
    provider.FromXmlString(xmlPublicKey);
    byte[] bytes = new UnicodeEncoding().GetBytes(enptStr);
    return Convert.ToBase64String(provider.Encrypt(bytes, RSAEncryptionPadding.OaepSHA1));
}

然後我們測試一下加密解密,測試函數如下。

public static void RsaTest()
{
    string myname = "my name is Kiba518!";
    Console.WriteLine($"內容:{myname}");
    string enStr = RSAEncrypt(publicKey, myname);
    Console.WriteLine($"加密字符串:{enStr}");
    string deStr = RSADecrypt(privateKey, enStr);
    Console.WriteLine($"解密字符串:{enStr}");
}

運行結果,加密解密成功,如下圖所示:

長字符分段加密

Rsa加密有字節數限制,即待加密的字符串太長,系統就會拋出異常:【System.Security.Cryptography.CryptographicException:“不正確的長度】

Rsa加密具體限制內容如下:

待加密的字節數不能超過密鑰的長度值除以 8 再減去 11(即:RSACryptoServiceProvider.KeySize / 8 – 11),而加密后得到密文的字節數,正好是密鑰的長度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)。

分段加密

為解決長字符加密的異常,我們採取分段加密的方法進行字符串加密,代碼如下:

//加密
public static String SubRSAEncrypt(string xmlPublicKey, string enptStr)
{ 
    RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
    provider.FromXmlString(xmlPublicKey);
    Byte[] bytes = Encoder.GetBytes(enptStr);
    int MaxBlockSize = provider.KeySize / 8 - 11;    //加密塊最大長度限制
​
    if (bytes.Length <= MaxBlockSize)
        return Convert.ToBase64String(provider.Encrypt(bytes, false));
​
    using (MemoryStream PlaiStream = new MemoryStream(bytes))
    using (MemoryStream CrypStream = new MemoryStream())
    {
        Byte[] Buffer = new Byte[MaxBlockSize];
        int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
​
        while (BlockSize > 0)
        {
            Byte[] ToEncrypt = new Byte[BlockSize];
            Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);
​
            Byte[] Cryptograph = provider.Encrypt(ToEncrypt, false);
            CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
​
            BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
        }
​
        return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
    } 
}
//解密
public static String SubRSADecrypt(string xmlPublicKey, string enptStr)
{ 
    RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
    provider.FromXmlString(xmlPublicKey);
    Byte[] bytes = Convert.FromBase64String(enptStr);
    int MaxBlockSize = provider.KeySize / 8;    //解密塊最大長度限制
​
    if (bytes.Length <= MaxBlockSize)
        return Encoder.GetString(provider.Decrypt(bytes, false));
​
    using (MemoryStream CrypStream = new MemoryStream(bytes))
    using (MemoryStream PlaiStream = new MemoryStream())
    {
        Byte[] Buffer = new Byte[MaxBlockSize];
        int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
​
        while (BlockSize > 0)
        {
            Byte[] ToDecrypt = new Byte[BlockSize];
            Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize); 
            Byte[] Plaintext = provider.Decrypt(ToDecrypt, false);
            PlaiStream.Write(Plaintext, 0, Plaintext.Length); 
            BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
        } 
        return Encoder.GetString(PlaiStream.ToArray());
    }
}  

編寫分段加密測試函數如下:

public static void SubRsaTest()
{
    string myname = "my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!";
    Console.WriteLine($"內容:{myname}");
    string enStr = SubRSAEncrypt(publicKey, myname);
    Console.WriteLine($"加密字符串:{enStr}");
    string deStr = SubRSADecrypt(privateKey, enStr);
    Console.WriteLine($"解密字符串:{deStr}");
}

運行結果,加密解密成功,如下圖:

關於證書

文中創建的證書—Kiba518.pfx,就是https所使用的證書,換言之,https的證書就是個Rsa加密解密文件。

當然正式的可以在互聯網中被各大網站認可的證書,是需要權威機構認證的,這個機構叫做CA,這個機構頒發的證書是.crt後綴名;而我們的pfx後綴名的證書,學名叫做個人信息交換證書。

其實它們沒有什麼區別,就是套的殼子不一樣,crt證書的殼子里多一些屬性,比如認證機構,有效期等等。但兩個證書的核心內容是一樣的,都是Rsa加密解密文件。

下面我們簡單了解下證書的導入。

導入證書

在運行窗口(window+r)輸入mmc打開microsoft管理控制台。

然後操作文件 -> 添加/刪除管理單元,選擇可用的管理單元中的證書點擊添加。

添加完管理單元,在右側控制台根節點會增加一個證書的根節點,如下圖:

然後,我們展開節點,找到【個人—證書】節點,然後【右鍵—所有任務—導入】。

然後按嚮導提示導入證書。

需要注意的是瀏覽導入證書的對話框,默認導入的是crt類型,我們需要點擊下拉菜單,選擇人信息交換選項,如下圖。

—————————————————————————————————-

到此Rsa加密解密的基本使用已經介紹完了。

代碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/RsaDemo

—————————————————————————————————-

注:此文章為原創,任何形式的轉載都請聯繫作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點擊下方的【推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/13141981.html

 

 

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

【其他文章推薦】

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

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

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

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

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

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

從零開始學習Prometheus監控報警系統

Prometheus簡介

Prometheus是一個開源的監控報警系統,它最初由SoundCloud開發。

2016年,Prometheus被納入了由谷歌發起的Linux基金會旗下的雲原生基金會( Cloud Native Computing Foundation),並成為僅次於Kubernetes的第二大開源項目。自此,它成為了一個獨立的開源項目,獨立於任何公司進行維護。

Prometheus擁有非常活躍的開發人員和用戶社區,目前在GitHub上已擁有三萬多的Star。

Prometheus特點

  • 提供多維度數據模型,使用指標名稱和鍵值對標識的時間序列數據
  • 提供靈活的PromQL查詢方式,還提供了HTTP查詢接口,可以很方便地結合Grafana等組件展示數據。
  • 不依賴外部存儲,支持單節點的本地存儲。通過Prometheus自帶的時序數據庫,可以完成每秒百萬及的數據存儲,如果需要存儲大量歷史數據,還可以對接第三方的時序數據庫。
  • 時間序列收集通過HTTP的拉取方式進行,並提供了開放的指標數據標準。
  • 支持向中間網關推送時序數據,可以更加靈活地適用於多種監控場景。
  • 支持通過動態服務發現和靜態文件配置獲取監控對象,目前已支持Kubernetes、Etcd、Consul等多種服務發現機制。
  • 支持多種模式的圖形展示和儀錶盤。
  • 大多數Prometheus的組件都是使用Go語言編寫的,這使得它們很容易以二進制文件的形式構建和部署。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

Prometheus架構

Prometheus生態圈由多個組件構成,其中許多組件是可選的:

  • Prometheus Server:用於收集、存儲和查詢時間序列數據。通過靜態配置文件管理監控目標,也可以配合使用動態服務發現的方式動態管理監控目標,並從這些監控目標中獲取數據。它將採集到的數據按照時間序列的方式存儲在本地磁盤當中或者外部的時序數據庫中,可通過PromQL語言對數據的查詢以及分析。
  • Client Library:為被監控的應用生成相應的指標(Metric)數據並暴露給Prometheus Server。當Prometheus Server 來拉取時,直接返回實時狀態的指標數據。
  • Push Gateway:主要用於短期存在的Jobs。由於這類Jobs存在時間較短,可能在Prometheus Server來拉取數據之前就消失了。所以,Jobs可以直接向Push Gateway推送它們的指標數據,然後Prometheus Server再從Push Gateway拉取。
  • Exporters:用於暴露已有的第三方服務的指標數據通過HTTP服務的形式暴露給Prometheus Server,比如HAProxy、StatsD、Graphite等等。Prometheus Server通過訪問該Exporter提供的Endpoint,即可獲取到需要採集的監控數據。
  • Alertmanager:從Prometheus Server接收到告警后,會進行去除重複數據,分組,並路由到對收的接受方式,發出報警。Alertmanager的告警方式非常靈活,支持通過郵件、slack或釘釘等多種途徑發出告警。
  • 一些其他的組件。

下面這張圖展示了Prometheus的架構和各個組件是如何交互和協作的:

其大概的工作流程是:

  1. Prometheus Server直接從HTTP接口或者Push Gateway拉取指標(Metric)數據。
  2. Prometheus Server在本地存儲所有採集的指標(Metric)數據,並在這些數據上運行規則,從現有數據中聚合和記錄新的時間序列,或者生成告警。
  3. Alertmanager根據配置文件,對接收到的告警進行處理,發出報警。
  4. 在Grafana或其他API客戶端中,可視化收集的數據。

Prometheus數據模型

Prometheus會將所有採集到的監控數據以時間序列的方式保存在內存數據庫中,並且定時保存到硬盤上。每一條數據由以下三部分組成:

  • 指標(Metric):由指標名稱和描述當前數據特徵的標籤組成。
  • 時間戳(Timestamp):一個精確到毫秒的時間戳。
  • 數據值(Value):一個float64的浮點型數據表示當前數據的值。

其中,指標(Metric)通過如下格式標識:

<指標名稱>{<標籤名稱>=<標籤值>, ...}

指標名稱(Metric Name)可以反映被監控數據的含義。指標名稱只能由ASCII字符、数字、下劃線以及冒號組成並必須符合正則表達式[a-zA-Z_:][a-zA-Z0-9_:]*。
標籤(Label)反映了當前數據的特徵維度,通過這些維度Prometheus可以對數據進行過濾,聚合等操作。標籤的名稱只能由ASCII字符、数字以及下劃線組成並滿足正則表達式[a-zA-Z_][a-zA-Z0-9_]*。

比如:

prometheus_http_requests_total{code="200",handler="/metrics"}

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

指標類型

Prometheus定義了4種不同的指標類型(Metric Type):

  • Counter(計數器)
  • Gauge(儀錶盤)
  • Histogram(直方圖)
  • Summary(摘要)

Counter(計數器)

Counter類型和計數器一樣,只增不減(除非系統發生重置),一般在定義Counter類型指標的名稱時推薦使用_total作為後綴。

比如,Prometheus Server中prometheus_http_requests_total, 表示Prometheus處理的HTTP請求總數:

# HELP prometheus_http_requests_total Counter of HTTP requests.
# TYPE prometheus_http_requests_total counter
prometheus_http_requests_total{code="200",handler="/api/v1/label/:name/values"} 3
prometheus_http_requests_total{code="200",handler="/api/v1/query"} 5
prometheus_http_requests_total{code="200",handler="/api/v1/query_range"} 15
prometheus_http_requests_total{code="200",handler="/graph"} 3
prometheus_http_requests_total{code="200",handler="/metrics"} 23
prometheus_http_requests_total{code="200",handler="/static/*filepath"} 18
prometheus_http_requests_total{code="302",handler="/"} 1

Gauge(儀錶盤)

Gauge類型側重於反應系統的某一個瞬時的值,這類指標的數據可增可減。

比如,Prometheus Server中go_threads, 表示Prometheus當前go線程的數量:

# HELP go_threads Number of OS threads created.
# TYPE go_threads gauge
go_threads 13

Histogram(直方圖)

Histogram類型由 _bucket{le=” “}, _bucket{le=”+Inf”}, _sum, _count 組成,主要用於表示一段時間範圍內對數據進行採樣,並能夠對其指定區間以及總數進行統計,通常它採集的數據展示為直方圖。

比如,Prometheus Server中prometheus_http_response_size_bytes:

# HELP prometheus_http_response_size_bytes Histogram of response size for HTTP requests.
# TYPE prometheus_http_response_size_bytes histogram
prometheus_http_response_size_bytes_bucket{handler="/",le="100"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="1000"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="10000"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="100000"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="1e+06"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="1e+07"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="1e+08"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="1e+09"} 1
prometheus_http_response_size_bytes_bucket{handler="/",le="+Inf"} 1
prometheus_http_response_size_bytes_sum{handler="/"} 29
prometheus_http_response_size_bytes_count{handler="/"} 1

Summary(摘要)

Summary類型由 {quantile=”<φ>”}, _sum, _count 組成,主要用於表示一段時間內數據採樣結果,它直接存儲了分位數據,而不是根據統計區間計算出來的。

比如,Prometheus Server中prometheus_target_interval_length_seconds:

# HELP prometheus_target_interval_length_seconds Actual intervals between scrapes.
# TYPE prometheus_target_interval_length_seconds summary
prometheus_target_interval_length_seconds{interval="15s",quantile="0.01"} 14.9986249
prometheus_target_interval_length_seconds{interval="15s",quantile="0.05"} 14.998999
prometheus_target_interval_length_seconds{interval="15s",quantile="0.5"} 15.0000428
prometheus_target_interval_length_seconds{interval="15s",quantile="0.9"} 15.0012009
prometheus_target_interval_length_seconds{interval="15s",quantile="0.99"} 15.0016468
prometheus_target_interval_length_seconds_sum{interval="15s"} 315.0013755
prometheus_target_interval_length_seconds_count{interval="15s"} 21

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

安裝Prometheus Server

從官方網站(https://prometheus.io/download/)上找到最新版本的Prometheus Sevrer軟件包,如下圖:
根據自己的系統下載對應的壓縮包,這裏以Windows為例,下載prometheus-2.19.0.windows-amd64.tar.gz。

解壓后當前目錄會包含默認的Prometheus配置文件promethes.yml:

# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ['localhost:9090']

暫且不做修改,雙擊prometheus.exe即可啟動,如下圖:

訪問http://localhost:9090/graph,就可以看到Prometheus自身的監控數據:

尾聲

Prometheus的大致介紹已經告一段落了,但是只是萬里長征的第一步,Prometheus的更多強大功能和使用方法還等待我們去挖掘。

微信公眾號:萬貓學社

微信掃描二維碼

獲得更多Java技術乾貨

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

【其他文章推薦】

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

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

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※新北清潔公司,居家、辦公、裝潢細清專業服務

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

一起玩轉微服務(9)——前後端分離

前後端分離

在傳統的web應用開發中,大多數的程序員會將瀏覽器作為前後端的分界線。將瀏覽器中為用戶進行頁面展示的部分稱之為前端,而將運行在服務器,為前端提供業務邏輯和數據準備的所有代碼統稱為後端。 由於前後端分離這個概念相對來說剛出現不久,很多人都是只聞其聲,不見其形,所以可能會對它產生一些誤解,誤以為前後端分離只是一種web應用開發模式,只要在web應用的開發期進行了前後端開發工作的分工就是前後端分離。 其實前後端分離並不只是開發模式,而是web應用的一種架構模式。在開發階段,前後端工程師約定好數據交互接口,實現并行開發和測試;在運行階段前後端分離模式需要對web應用進行分離部署,前後端之前使用HTTP或者其他協議進行交互請求。 前後端分離原則,簡單來講就是前端和後端的代碼分離也就是技術上做分離。推薦的模式是最好直接採用物理分離的方式部署,進一步促使進行更徹底的分離。不要繼續以前的服務端模板技術,比如JSP ,把Java JS HTML CSS 都堆到一個頁面里,稍複雜的頁面就無法維護。

好處

這種分離模式的方式有幾個好處:

•前後端技術分離,可以由各自的專家來對各自的領域進行優化,這樣前端的用戶體驗優化效果會更好。•分離模式下,前後端交互界面更加清晰,就剩下了接口和模型,後端的接口簡潔明了,更容易維護。•前端多渠道集成場景更容易實現,後端服務無需變更,採用統一的數據和模型,可以支撐前端的web UI\ 移動App等訪問。

前後端分離意味着,前後端之間使用 JSON 來交流,兩個開發團隊之間使用 API 作為契約進行交互。從此,後台選用的技術棧不影響前台。 前後端分離並非僅僅只是前後端開發的分工,而是在開發期進行代碼存放分離、前後端開發職責分離,前後端能夠獨立進行開發測試;在運行期進行應用部署分離,前後端之間通過HTTP請求進行通訊。前後端分離的開發模式與傳統模式相比,能為我們提升開發效率、增強代碼可維護性,讓我們有規劃地打造一個前後端並重的精益開發團隊,更好地應對越來越複雜多變的Web應用開發需求。 前後端分離的核心:後台提供數據,前端負責显示。

常見的前端

AngularJS

Angular JS (Angular.JS) 是一組用來開發 Web 頁面的框架、模板以及數據綁定和豐富 UI 組件。它支持整個開發進程,提供 Web 應用的架構,無需進行手工 DOM 操作。 AngularJS 很小,只有 60K,兼容主流瀏覽器,與 jQuery 配合良好。

數據綁定可能是 AngularJS 最酷最實用的特性。它能夠幫助你避免書寫大量的初始代碼從而節約開發時間。一個典型的 Web 應用可能包含了 80% 的代碼用來處理,查詢和監聽 DOM。數據綁定使得代碼更少,你可以專註於你的應用。

傳統來說,當 Model 變化了。 開發人員需要手動處理 DOM 元素並且將屬性反映到這些變化中。這個一個雙向的過程。一方面,Model 變化驅動了 DOM 中元素變化,另一方面,DOM 元素的變化也會影響到 Model。這個在用戶互動中更加複雜,因為開發人員需要處理和解析這些互動,然後融合到一個 Model 中,並且更新 View。這是一個手動的複雜過程,當一個應用非常龐大的時候,將會是一件非常費勁的事情。

特性二:模板

在 AngularJS 中,一個模板就是一個 HTML 文件。但是 HTML 的內容擴展了,包含了很多幫助你映射 Model 到 View 的內容。

HTML 模板將會被瀏覽器解析到 DOM 中。DOM 然後成為 AngularJS 編譯器的輸入。AngularJS 將會遍歷 DOM 模板來生成一些指導,即,directive(指令)。所有的指令都負責針對 View 來設置數據綁定。

我們要理解 AuguarJS 並不把模板當做 String 來操作。輸入 AngularJS 的是 DOM 而非 string。數據綁定是 DOM 變化,不是字符串的連接或者 innerHTML 變化。使用 DOM 作為輸入,而不是字符串,是 AngularJS 區別於其它的框架的最大原因。使用 DOM 允許你擴展指令詞彙並且可以創建你自己的指令,甚至開發可重用的組件。

特性三:MVC

針對客戶端應用開發 AngularJS 吸收了傳統的 MVC 基本原則。MVC 或者 Model-View-Controll 設計模式針對不同的人可能意味不同的東西。AngularJS 並不執行傳統意義上的 MVC,更接近於 MVVM(Model-View-ViewModel)。

特性四:依賴注入(Dependency Injection,即 DI)

AngularJS 擁有內建的依賴注入子系統,可以幫助開發人員更容易的開發,理解和測試應用。

DI 允許你請求你的依賴,而不是自己找尋它們。比如,我們需要一個東西,DI 負責找創建並且提供給我們。

特性五:Directives(指令)

指令是我個人最喜歡的特性。你是不是也希望瀏覽器可以做點兒有意思的事情?那麼 AngularJS 可以做到。
指令可以用來創建自定義的標籤。它們可以用來裝飾元素或者操作 DOM 屬性。

2. React

React 是一個用於構建用戶界面的 JAVASCRIPT 庫。
React 主要用於構建UI,很多人認為 React 是 MVC 中的 V(視圖)。
React 起源於 Facebook 的內部項目,用來架設 Instagram 的網站,並於 2013 年 5 月開源。
React 擁有較高的性能,代碼邏輯非常簡單,越來越多的人已開始關注和使用它。
使用 React 可以將一些簡短、獨立的代碼片段組合成複雜的 UI 界面,這些代碼片段被稱作“組件”。

React特點

  1. 聲明式設計 −React採用聲明範式,可以輕鬆描述應用。

  2. 高效 −React通過對DOM的模擬,最大限度地減少與DOM的交互。

  3. 靈活 −React可以與已知的庫或框架很好地配合。

  4. JSX − JSX 是 JavaScript 語法的擴展。React 開發不一定使用 JSX ,但我們建議使用它。

  5. 組件 − 通過 React 構建組件,使得代碼更加容易得到復用,能夠很好的應用在大項目的開發中。

  6. 單向響應的數據流 − React 實現了單向響應的數據流,從而減少了重複代碼,這也是它為什麼比傳統數據綁定更簡單。

Vue.js

Vue.js(讀音 /vjuː/, 類似於 view) 是一套構建用戶界面的漸進式框架。

Vue 只關注視圖層, 採用自底向上增量開發的設計。

Vue 的目標是通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件。

 

 

Kotlin

Kotlin 是一種在 Java 虛擬機上運行的靜態類型編程語言,被稱之為 Android 世界的Swift,由 JetBrains 設計開發並開源。

Kotlin 可以編譯成Java字節碼,也可以編譯成 JavaScript,方便在沒有 JVM 的設備上運行。

在Google I/O 2017中,Google 宣布 Kotlin 成為 Android 官方開發語言。

 

5. Flutter

 

Flutter 由 Google 的工程師團隊打造,用於創建高性能、跨平台的移動應用。Flutter 針對當下以及未來的移動設備進行優化,專註於 Android and iOS 低延遲的輸入和高幀率。

Flutter 可以給開發者提供簡單、高效的方式來構建和部署跨平台、高性能移動應用;給用戶提供漂亮、快速、jitter-free 的 app 體驗。

Flutter 的主要組件:

  • 一個高度優化, mobile-first 2D 渲染引擎 (保護對 text 優秀的支持 )

  • 一個 functional-reactive 框架 (可選的,你也可以引入你自己的框架)

  • 一組 Material Design 部件 (可選的,你也可以引入你自己的部件)庫 ,工具,和一個用於 Atom 的插件。

6. .Net

.NET是 Microsoft XML Web services 平台。XML Web services 允許應用程序通過 Internet 進行通訊和共享數據,而不管所採用的是哪種操作系統、設備或編程語言。Microsoft .NET 平台提供創建 XML Web services 並將這些服務集成在一起之所需。對個人用戶的好處是無縫的、吸引人的體驗。

這個不用說了,很大一部分人一直在用,而且作為master語言。但是對於微服務程序,感覺更適合於前端應用或者一些輕量級企業級的開發。

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

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

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

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

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

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

英研究稱城市臭氧污染與死亡風險增加相關

摘錄自2020年2月17日北京新浪網報導

倫敦大學衛生和熱帶醫學院最近發佈一項研究說,對全球數百個城市的調查發現,人們日常暴露在城市地面臭氧污染中與死亡風險增加有關。

來自該學院以及多個科研機構的國際團隊在最新一期《英國醫學雜誌》上發表文章報告稱,他們採集了1985年至2015年間來自20個國家和地區406個城市的4500多萬例死亡案例相關數據,並分析了這些城市的污染狀況及死亡風險間的關係後發現,城市地面臭氧水平平均每上升10微克/立方米,總體死亡風險就會增加0.18%。也就是說,如果這些城市執行了更嚴格的空氣排放標準,每年共可減少6000多人死亡。

但團隊也表示,這項研究是基於觀察性分析,因此無法直接確立因果關係,研究結果的準確性也受到一些因素的限制。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

研究:野火危機影響75%澳洲人 當局支持率暴跌

摘錄自2020年2月18日中央社報導

澳洲野火延燒5個月,據今天(18日)公布的最新調查,澳洲75%民眾、將近1800萬人自認受到這波致命野火危機影響。調查也顯示,野火這一燒,同時燒掉了政府和煤炭計畫的支持率。

法新社報導,澳洲國立大學(Australian National University)社會研究主筆畢德爾(Nicholas Biddle)表示:「這場火災幾乎影響到每個澳洲民眾,這將會影響我們許多人好幾年。」

這項訪問3000人的調查指出,14%成人受到直接影響,他們的房屋沒了或受損,或是全家被迫撤離。

除了近300萬人直接受衝擊,更有1500萬名澳洲人受到間接影響,包括受野火煙霧影響或度假計畫泡湯。

上次大選支持政府的受訪者中,支持新建煤礦場的比例從野火危機前的72%跌到1月的57%。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

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

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

哥倫比亞毒梟艾斯科巴的河馬 意外恢復1萬多年前部分生態系功能

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

三星和半導體工人組織就白血病爭議達成妥協

摘錄自2018年月日[媒體名稱][地點]報導

韓聯社報導,三星電子、半導體工人健康與人權守護組織(簡稱半導體工人組織)及調解委員會24日上午舉行「第二次重啟調解及仲裁方式協議簽字儀式」,三星和半導體工人組織承諾今後無條件接受調解委提出的方案。

調解委將於8-9月製定調解方案,在9月底到10月初發表第二次調解最終方案,三星電子爭取在10月內對半導體工人組織的受害者提供賠償。

2007年,在三星電子半導體生產線工作的黃某因患急性白血病不幸身亡。此後,白血病等疾病是否與三星半導體工廠有關引起了爭議。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

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

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

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