Tomcat(五):nginx/httpd + tomcat及負載均衡tomcat

来源:https://www.cnblogs.com/f-ck-need-u/archive/2018/02/04/8414043.html
-Advertisement-
Play Games

本文目錄:1. Tomcat連接器協議類型2. Tomcat與httpd/nginx結合的方式3. Tomcat + nginx4. Tomcat + httpd(mod_jk) 4.1 編譯mod_jk模塊 4.2 配置httpd與tomcat的ajp連接 4.3 通過mod_jk負載均衡tomc ...


本文目錄:
1. Tomcat連接器協議類型
2. Tomcat與httpd/nginx結合的方式
3. Tomcat + nginx
4. Tomcat + httpd(mod_jk)
 4.1 編譯mod_jk模塊
 4.2 配置httpd與tomcat的ajp連接
 4.3 通過mod_jk負載均衡tomcat
5. Tomcat+httpd(mod_proxy)
 5.1 配置httpd代理到tomcat
 5.2 通過mod_proxy負載均衡tomcat

tomcat一般只提供動態資源處理功能,而靜態資源的請求則交給獨立的apache/httpd或nginx來處理。但tomcat與外界通信的唯一組件是連接器Connector,因此動態請求要轉發給tomcat時,需要和Connector通信。Connector與外界通信的協議有兩種:http/ajp。

1. Tomcat連接器協議類型

tomcat的Connector組件支持兩種協議類型的連接:http、ajp。

其中http又分為http/1.1和http/2,但因為Servlet的阻塞特性,使得每個http/2的請求都需要單獨的容器線程負責處理,因此目前使用http/2的性能還很差。而AJP又有ajp12、ajp13和ajp14,其中ajp12的功能太簡陋,ajp14又處於試驗期,因此目前都適用ajp13,或者稱為ajp 1.3。

基於IO模型,Connector又分為NIO/NIO2/APR三種類型。

設置連接器協議的方式如下:

<!--  定義使用Http協議的連接器,其中"HTTP/1.1"表示自動選擇NIO/NIO2/APR  -->
<connector port="8080" protocol="HTTP/1.1">
<connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol">

<!--  定義使用AJP協議的連接器,其中"AJP/1.3"表示自動選擇NIO/NIO2/APR  -->
<Connector port="8009" protocol="AJP/1.3"/>
<Connector port="8009" protocol="org.apache.coyote.ajp.AjpNioProtocol"/>
<Connector port="8009" protocol="org.apache.coyote.ajp.AjpNio2Protocol"/>
<Connector port="8009" protocol="org.apache.coyote.ajp.AjpAprProtocol"/>

2. Tomcat與httpd/nginx結合的方式

Tomcat連接器與外界通信的兩種協議中,ajp只能和apache基金會開發的部分項目通信,例如httpd。要與非apache基金會開發的程式通信,必須使用http協議。因此,tomcat+nginx時,tomcat連接器的協議類型只能是http。

對於tomcat+httpd,tomcat端的連接器既可以使用http,也可以使用ajp協議。但在httpd端,也支持多種通信模塊,最常用的是mod_proxy和mod_jk。

tomcat+httpd時,幾個需要註意的點:

  • (1).mod_jk一般只和tomcat的ajp協議配合來通信。而mod_proxy則不要求tomcat端的協議類型是http還是ajp。
  • (2).配置時,使用mod_jk比使用mod_proxy要複雜的多。
  • (3).使用mod_jk可以配置成只處理動態請求,而不處理靜態請求。但mod_proxy則只能將所有請求都轉發給tomcat。因此,在性能上mod_jk比mod_proxy。不過由於前端可以使用反向代理工具,因此這種情況下的mod_jk和mod_proxy,性能無差別。

因此,如果滿足業務需求,建議使用mod_proxy,它配置起來比mod_jk要簡便的多,且可定製的功能更多。

稍作總結,apache和tomcat通信的實現方式有3種:

apache:mod_jk  <--> tomcat:ajp(雖然可以和http配合,但不建議)
apache:mod_proxy <--> tomcat:ajp或http

下圖是httpd/nginx+tomcat在動靜分離時通常使用的架構模型。

左邊的模型中,nginx/httpd需要處理靜態請求,並將動態請求轉發給tomcat,同時實現負載均衡。右邊的模型中,添加一層反向代理層,無論是靜態請求還是動態請求都負載到各自的伺服器組。後文的實驗都採用左邊的架構模型來完成。

3. Tomcat + nginx

測試環境如下:

[root@xuexi ~]# echo "[nginx]
name=nginx
baseurl=http://nginx.org/packages/centos/6/x86_64/
enable=1
gpgcheck=0" >/etc/yum.repos.d/nginx.repo

[root@xuexi ~]# yum install -y nginx
[root@xuexi ~]# vim /etc/nginx/conf.d/tomcat.conf
upstream tomcat_servers {
    server 192.168.100.22:8080 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.100.23:8080 weight=2 max_fails=2 fail_timeout=2;
}

server {
    listen       80;
    server_name  192.168.100.17;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location ~* \.(jsp|jspx|do) {
        proxy_pass http://tomcat_servers;
    }
}

啟動nginx和tomcatA、tomcatB。然後在瀏覽器中分別訪問靜態資源和動態資源。

http://192.168.100.17
http://192.168.100.17/index.jsp

其中第二個訪問的是動態資源,頁面結果如下:

發現這個歡迎頁面缺失了很多內容。其實這些缺失的內容都是定義在index.jsp中的靜態資源,例如某些圖片。之所以會缺失,是因為客戶端發送請求給nginx後,nginx將請求轉發給tomcat,tomcat翻譯index.jsp為java源文件,然後執行該servlet。執行servlet時,將所需響應數據都回應給nginx,包括index.jsp中定義的圖片鏈接標簽。當客戶端收到這一次的響應數據後,還會繼續去請求圖片,但是這是靜態請求,nginx會自己處理而不會轉發給tomcat,但nginx本身不知道圖片在何處(tomcat才知道)。因此對於圖片部分,nginx將返回404錯誤,使得客戶端顯示的頁面缺失了一部分。

在生產環境下,不需要擔心這樣的二次靜態請求缺失問題,因為會將圖片等靜態數據存放在某個位置,並配置好nginx如何找到這些靜態數據。

4. Tomcat + httpd(mod_jk)

測試環境如下:

使用mod_jk模塊和tomcat連接時,tomcat的連接器一般都使用ajp協議類型。

mod_jk不是apache httpd的原生模塊,而是類似於第三方模塊,因此需要額外編譯mod_jk模塊到httpd中,就像將php模塊添加到httpd中一樣。

4.1 編譯mod_jk模塊

當前最新穩定版的mod_jk是1.2.42版本。

mod_jk下載地址:http://tomcat.apache.org/download-connectors.cgi
mod_jk官方手冊:http://tomcat.apache.org/connectors-doc/

httpd要擴展模塊需要藉助apxs,它是httpd的開發包httpd-devel中工具,所以先要安裝httpd-devel。如果是編譯安裝的httpd,則devel包已經裝好,如果是yum安裝,則需要額外安裝httpd-devel包。

此處為了方便,httpd使用yum安裝。所以編譯mod_jk的方式如下:

yum -y install httpd httpd-devel
tar xf tomcat-connectors-1.2.42-src.tar.gz
cd tomcat-connectors-1.2.42-src/native/
./configure --with-apxs=/usr/bin/apxs --prefix=/usr/local/tomcat/mod_jk
make && make install

4.2 配置httpd與tomcat的ajp連接

此處暫先配置httpd與其中一個tomcat(192.168.100.22)連接。後文在說明負載均衡時再引入另一個tomcat。

先提供一個額外的httpd配置文件。

[root@xuexi ~]# cat /etc/httpd/conf.d/mod_jk.conf
LoadModule  jk_module  modules/mod_jk.so
JkWorkersFile  /etc/httpd/conf.d/workers.properties
JkLogFile  logs/mod_jk.log
JkLogLevel  debug
######### "JkMount /* TomcatA" will send all request to TomcatA   ########
JkMount   /*.jsp        TomcatA
JkMount   /status/*     statA
JkUnMount /images/*     TomcatA
JkUnMount /css/*.*      TomcatA
JkUnMount /css_js/*     TomcatA
JkUnMount /*.html       TomcatA
JkUnMount /*.js         TomcatA

mod_jk的配置文件官方手冊:http://tomcat.apache.org/connectors-doc/reference/apache.html。以下是幾個常用的指令說明。

  • LoadModule指令用於裝載mod_jk相關模塊,除此之外還需要在httpd的配置文件中設置其它一些指令來配置其工作屬性。如:
  • JkWorkersFile用於指定保存了worker相關工作屬性定義(見下文)的配置文件。
  • JkLogFile用於指定mod_jk模塊的日誌文件。
  • JkLogLevel用於指定日誌級別(info,error,debug),此外還可以使用JkRequestLogFormat自定義日誌信息格式。
  • JkMount(格式:JkMount )則用於控制URL與Tomcat workers的對應關係。可以理解為轉發請求的意思,例如"/status/*"表示url地址後加上/status/可轉發至statA這個worker上。註意,JkMount匹配的URL是相對的。如果JkMount指令放在Location指令中,如<Location /app>,則JkMount將從/app的後面開始匹配。

JkMount和JkUnMount是很重要的指令,mod_jk性能之所以比mod_proxy好,就是因為通過這兩個指令可以實現動靜分離,使得只將動態請求轉發給tomcat。其中JkMount指定要轉發給tomcat處理的請求,JkUnMount指定明確不轉發給tomcat而是在本地處理的請求雖然不指定JkUnMount時,也表示不轉發給tomcat,但如果有重疊時,則應該指定JkUnMount。例如下麵的例子,除了/myapp/下的js文件,其他都轉發給tomcat1處理。

JkMount /myapp/* tomcat1
JkUnMount /myapp/*.js tomcat1

對於apache來說,每一個後端Tomcat實例中的engine都可以視作一個worker,而每一個worker的地址、Connector的埠等信息都需要在apache端指定以便可以識別並使用這些worker。配置這些信息的文件通常為"workers.properties",其具體路徑是使用前面介紹過的JkWorkersFile指定的。在apache啟動時,mod_jk會掃描此文件獲取每一個worker配置信息。如這裡使用/etc/httpd/conf.d/workers.properties

workers.properties文件一般由兩類指令組成:一是mod_jk可以連接的各worker名稱列表,二是每一個worker的屬性配置信息。詳細的配置方法見官方手冊:http://tomcat.apache.org/connectors-doc/reference/workers.html

以下是和上述/etc/httpd/conf.d/mod_jk.conf中配置相對應的/etc/httpd/conf.d/workers.properties。

[root@xuexi tomcat]# cat /etc/httpd/conf.d/workers.properties
worker.list=TomcatA,statA
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.100.22
worker.TomcatA.port=8009
worker.TomcatA.lbfactor=1
worker.statA.type = status

關於worker的配置,它們分別遵循如下使用語法。

worker.list = <a comma separated list of worker_name>
worker.<worker_name>.<property>=<property value>

其中worker.list指令可以重覆指定多次。worker_name是Tomcat中engine組件中jvmRoute屬性的值(jvmRoute可以不指定,此時worker_name僅用於標識worker)。

根據工作機制的不同,worker有多種不同的類型,每個worker都需要指定其類型,即設定woker..type項。常見的類型如下:其中ajp13是預設值。

  • ajp13:此類型是web server和tomcat首選的類型。此外,還有ajp12和ajp14,但它們一個廢棄一個處於測試階段。
  • lb:lb用於負載均衡場景中的worker;此worker並不真正負責處理用戶請求,而是將用戶請求調度給其它類型為ajp13的worker。
  • status:用戶顯示負載均衡中各worker工作狀態的特殊worker,它不處理任何請求,也不關聯到任何實際工作的tomcat實例。

由於status是狀態監控頁面,所以應該保證其安全性,可以在httpd的配置文件中加入以下控制列表:

# 註意,必須加上尾隨斜線,因為在mod_jk.conf中已經明確了"/status/*"
# For http 2.2
<Location /status/>
    Order deny,allow
    Deny from all
    Allow from 192.168.100.0/24
</Location>

# For http 2.4
<Location /status/>
    Requrie ip 192.168.100
</Location>

除了type屬性外,worker其它常見的屬性有:

除了type屬性外,worker其它常見的屬性有:

  • host:worker所在的主機,更具體的是tomcat上connector組件設置的ajp監聽地址;
  • port:worker的AJP1.3連接器監聽的埠;
  • connection_pool_minsize:最少要保存在連接池中的連接的個數;預設為pool_size/2;
  • connection_pool_timeout:連接池中連接的超時時長;
  • mount:由當前worker提供的context路徑,如果有多個則使用空格格開;可考慮在httpd端使用JkMount替代。
  • retries:錯誤發生時的重試次數;
  • socket_timeout:mod_jk等待worker響應的時長,預設為0,即無限等待;
  • socket_keepalive:是否啟用keep alive的功能,1表示啟用,0表示禁用;
  • lbfactor:worker的權重,可以在負載均衡的應用場景中為worker定義此屬性;

另外,在負載均衡模式中專用的屬性還有:

  • balance_workers:用於負載均衡模式中的各worker的名稱列表,需要註意的是,出現在此處的worker名稱一定不能在任何worker.list屬性列表中定義過,並且worker.list屬性中定義的worker名字必須包含負載均衡worker。
  • method:可以設定為R、T或B;預設為R,即根據請求的個數進行調度(wrr);T表示根據已經發送給worker的實際流量大小進行調度;B表示根據實際負載情況進行調度(leastconn)。
  • sticky_session:將某請求調度至某worker後,此地址後續所有請求都將直接調度至此worker,實現將用戶session與某worker綁定。預設為值為true,即啟用此功能。如果後端的各worker之間支持session複製,則可設為false。

至此,一個基於mod_jk模塊與後端名為TomcatA的worker通信的配置已經完成,重啟httpd服務即可生效。

測試:在瀏覽器中輸入

http://192.168.100.17/
http://192.168.100.17/index.jsp
http://192.168.100.17/status/

如果都能獲取頁面,則表示apache通過mod_jk和tomcat基於ajp協議類型的連接已經成功。

4.3 通過mod_jk負載均衡tomcat

使用mod_jk實現tomcat的負載均衡有一個好處,tomcat上可以禁用http協議(將監聽此協議的Connector配置刪除即可),防止外界直接通過http請求tomcat。

配置apache,使其支持負載均衡,修改/etc/httpd/conf.d/mod_jk.conf為如下內容:

LoadModule      jk_module  modules/mod_jk.so
JkWorkersFile   /etc/httpd/conf.d/workers.properties
JkLogFile       logs/mod_jk.log
JkLogLevel      notice
JkMount         /*.jsp     TomcatLB
JkMount         /status/*  statA

編輯/etc/httpd/conf.d/workers.properties,修改為如下內容:為測試負載效果,不啟用stick_session。

worker.list=TomcatLB,statA
worker.statA.type=status
worker.TomcatLB.type=lb
worker.TomcatLB.sticky_session=false
worker.TomcatLB.balance_workers=TomcatA,TomcatB
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.100.22
worker.TomcatA.port=8009
worker.TomcatA.lbfactor=5
worker.TomcatB.type=ajp13
worker.TomcatB.host=192.168.100.23
worker.TomcatB.port=8009
worker.TomcatB.lbfactor=10

在mod_jk負載均衡中,後端tomcat的engine組件需要添加jvmRoute參數,該參數會為當前server實例設置全局惟一標識符,因此每一個實例的jvmRoute的值均不能相同,且jvmRoute的值必須等於balance_workers的成員值。對於上面的配置,Engine應該如下設置:此處還修改了name,但這不是要求要修改的。

<!--  在tomcatA上設置  -->
<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA">
<!--  在tomcatB上設置  -->
<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatB">

為了演示效果,在TomcatA部署一個應用程式test。

[root@xuexi tomcat]# mkdir -p /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}

添加index.jsp,內容如下:

[root@xuexi tomcat]# cat /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<html>
  <head><title>TomcatA</title></head>
  <body>
    <h1><font color="red">TomcatA </font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("abc","abc"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

在TomcatB同樣也部署一個應用程式test。如下:

[root@xuexi tomcat]# mkdir -p /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
[root@xuexi tomcat]# cat /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<html>
  <head><title>TomcatB</title></head>
  <body>
    <h1><font color="blue">TomcatB </font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("abc","abc"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

重啟httpd、tomcatA、tomcatB對應的服務程式。在瀏覽器中輸入192.168.100.17/test/index.jsp測試負載均衡是否生效。

測試時,輪調兩次tomcatB後輪調一次tomcatA。而且可以發現每次輪詢時Session ID每次都是變化的,因為沒有開啟sticky_session,所以session沒有進行綁定。

要綁定會話,將worker.properties中的sticky_session設置為true即可。

5. Tomcat+httpd(mod_proxy)

測試環境如下:

當httpd端採用mod_proxy和tomcat連接時,可以採用ajp或http協議進行連接。

要使用mod_proxy與Tomcat連接,需要apache已經裝載mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(實現Tomcat負載均衡時用到)等模塊。使用rpm包安裝的httpd一般預設已經啟用它們,如果是編譯httpd,則在編譯選項中加上以下對應幾項:

--enable-proxy --enable-proxy-http --enable-proxy-ajp --enable-proxy-balancer

如果是已經編譯好的Httpd,則可以使用apxs工具,向httpd中添加這幾個新模塊。添加方法見:httpd添加新模塊

確保proxy相關的模塊已經載入了。

[root@xuexi ~]# httpd -M | grep proxy 
Syntax OK
 proxy_module (shared)
 proxy_balancer_module (shared)
 proxy_ftp_module (shared)
 proxy_http_module (shared)
 proxy_ajp_module (shared)
 proxy_connect_module (shared)

5.1 配置httpd代理到tomcat

基於ajp連接協議和tomcat連接時,向httpd添加以下配置文件。如果要基於http協議連接tomcat,將上面配置文件的ajp協議改為http協議,並修改埠即可。

[root@xuexi ~]# cat /etc/httpd/conf.d/ajp.conf
<Location /status>
  SetHandler balancer-manager
  Proxypass !              # 表示此Location的URL不進行反向代理
  Require ip 192.168.100
</Location>

ProxyVia Off
ProxyRequests Off
ProxyPreserveHost Off
  ProxyPassMatch    "^/(.*\.jsp)$"  ajp://192.168.100.22:8009/$1
  ProxyPassReverse  "^/(.*\.jsp)$"  ajp://192.168.100.22:8009/$1

<Proxy *>
  Require all granted
</Proxy>

重啟httpd。註意,重啟前將前面mod_jk實驗的配置文件刪除掉。

關於如上apache配置的幾個指令,解釋如下。httpd反向代理的詳細內容,可參見:詳細分析apache httpd反向代理的用法

  • ProxyVia {On|Off|Full|Block}:用於控制在http首部是否使用"Via:",主要用於在多級代理中控制代理請求的流向。預設為Off,即不啟用此功能;On表示每個請求和響應報文均添加"Via:";Full表示每個"Via:"行都會添加當前apache伺服器的版本號信息;Block表示每個代理請求報文中的"Via:"都會被移除。
  • ProxyRequests {On|Off}:是否開啟apache正向代理的功能;如果為apache設置了ProxyPass即反向代理,則必須將ProxyRequests設置為Off。
  • ProxyPreserveHost {On|Off}:如果啟用此功能,代理會將用戶請求報文中的"Host:"行發送給後端的伺服器,而不再使用ProxyPass指定的伺服器IP地址。如果後端一個IP上可能會有多個虛擬主機,則需要開啟此項明確轉發給哪台虛擬主機,否則就無需打開此功能。
  • ProxyPassReverse:在反向代理環境中必須使用此指令避免重定向報文繞過proxy伺服器,屬性設置為ProxyPass一樣基本上就可以。
  • ProxyPass [path] !|[url [key=value key=value ...]]:將後端伺服器某URL與當前伺服器的某虛擬路徑關聯起來作為提供服務的路徑,path為當前伺服器上的某虛擬路徑,url為後端伺服器上某URL路徑。使用此指令時必須將ProxyRequests的值設置為Off。需要註意的是,如果path以"/"結尾,則對應的url也必須以"/"結尾,反之亦然。
  • ProxyPassMatch [regex] !|url [key=value [key=value ...]]:正則格式的ProxyPass。

5.2 通過mod_proxy負載均衡tomcat

關於httpd反向代理的負載均衡配置方式,參見詳細分析apache httpd反向代理的用法

在httpd.conf中配置如下內容:

<proxy balancer://TomcatLB>
BalancerMember ajp://192.168.100.38:8009 loadfactor=5
BalancerMember ajp://192.168.100.36:8009 loadfactor=10
</proxy>

ProxyVia Off
ProxyRequests Off
ProxyPreserveHost Off
ProxyPassMatch   "^/(.*\.jsp)$" balancer://TomcatLB/$1 
ProxyPassReverse "^/(.*\.jsp)$" balancer://TomcatLB/$1

<Proxy *>
  Require all granted
</Proxy>

<Location /status>
  SetHandler balancer-manager
  Proxypass ! 
  Require ip 192.168.100
</Location>

重啟httpd併在瀏覽器中輸入192.168.100.17/test/index.jsp測試,測試時會輪調兩次tomcatB再輪調一次tomcatA。

如果要實現session粘滯(綁定),則修改httpd配置文件如下:

<proxy balancer://TomcatLB>
BalancerMember ajp://192.168.100.22:8009 loadfactor=5  route=TomcatA
BalancerMember ajp://192.168.100.23:8009 loadfactor=10 route=TomcatB
ProxySet  lbmethod=byrequets
</proxy>

ProxyVia Off
ProxyRequests Off
ProxyPreserveHost Off
ProxyPassMatch   "^/(.*\.jsp)$" balancer://TomcatLB/$1 stickysession=JSESSIONID
ProxyPassReverse "^/(.*\.jsp)$" balancer://TomcatLB/$1 stickysession=JSESSIONID

<Proxy *>
  Require all granted
</Proxy>

<Location /status>
  SetHandler balancer-manager
  Proxypass ! 
  Require ip 192.168.100
</Location>

然後分別配置tomcatA和tomcatB的engine組件,分別加上jvmRoute="TomcatA"和jvmRoute="TomcatB"屬性。

<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatA">
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">

重啟httpd和tomcatA、tomcatB,然後測試結果,再測試時同一客戶端將總是得到同一個結果,不會出現負載均衡。

 

回到Linux系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
回到網站架構系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
回到資料庫系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7586194.html
轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/8414043.html

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 裝飾器: 意義:在不能改變原函數的源代碼,和在不改變整個項目中原函數的調用方式的情況下,給函數添加新的功能 由於不允許改變函數的源代碼,在忽略調用方式的情況下,我們可能會有以下結果: 但這改變了原本的調用方式,原本是test1(),現在是decorator(test1) 那麼如果我們為了使調用方式不 ...
  • 1.類變數的用途:大家公用的屬性,節省開銷(記憶體) 2.析構函數 在實例釋放和銷毀的時候執行的,通常用於做一些收尾工作,如關閉一些資料庫鏈接和打開的臨時文件 3.私有方法兩個下劃線開頭,聲明該方法為私有方法,不能在類地外部調用。 4.私有屬性兩個下劃線開頭,聲明該屬性為私有,不能在類地外部被使用或直 ...
  • 什麼是Tomcat Tomcat簡單的說就是一個運行JAVA的網路伺服器,底層是Socket的一個程式,它也是JSP和Serlvet的一個容器。 為什麼我們需要用到Tomcat 如果你學過html,css,你會知道你寫的頁面只能自己訪問, 別人不能遠程訪問你寫的頁面 ,Tomcat就是 提供能夠讓別 ...
  • Create the short array at half the size of the byte array, and copy the byte data in: It is the fastest method by far. https://stackoverflow.com/quest ...
  • 本文基於初次或再次嘗試部署.Net Core應用到Linux伺服器上,我嘗試後自我總結的經驗一個簡單的Demo,嘗試部署在Linux伺服器上和跨伺服器訪問資料庫。 一、環境介紹 1、本地使用Visual Studio 2017開發,使用的.NetCore SDK版本為2.1.4; 2、資料庫使用的M ...
  • Quartz 是什麼? Quartz 是作業調度系統,可以集成進其他軟體系統。這裡【作業調度程式】一詞是指,在預定義時間執行(或通知)其他組件的系統。 Quartz 有什麼優點? 靈活,有多種使用方式,可混合使用 輕量,只需很少的配置 容錯性好 具有持久化功能,程式重啟時,可記住已計劃的任務 Qua ...
  • Entity Framework Codefirst的配置步驟: (1) 安裝命令: install-package entityframework (2) 創建實體類,註意virtual關鍵字在導航屬性中的用法 (3) 創建DbContext類,為每個entity set創建一個DbSet; 指定 ...
  • 1. 實現DataGrid column的顯示和隱藏功能; (1). 定義ContextMenu ,該ContextMenu僅可使用於DataGrid的DataGridColumnHeader; (2). 自定義顯示隱藏的制轉換器; 2. 在實現DataGridColumn Filter 功能時,可 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...