欧美第十页,成人网成人A片,宾馆内激干人妻,偷偷内射,一区二区另类TS

MSXML 4.0 Service Pack 2

前沿拓展:

MSXML 4.0 Servi

MSXML全名是:「Microsoft XML Cor可普味電憲粒e Services」,主要是用來執(zhí)行或開發(fā)經(jīng)由 XML 所設(shè)計的最新應(yīng)用程序。
   微軟留揚左星巖吧曲傷陸附正式發(fā)布了其XML的核心服務(wù)組件—MSXML 4.0。和MSXML 3.0相比,MSXML 4.0提供了大量的新功能和功能改進。其中包括:對XML模式語言的支持,更快的分析器和XSLT引擎,對XML流更好的處理,更好的一致性支持。 MSXML 4.0并不是MSXML 3.0的替代產(chǎn)品,因為在3.0中的一些過時功能已經(jīng)在4.0中徹底去除了。所以4.0可以和3.0(甚至更早的版本)同時安裝。
  MSXML 4.0 Service Pack 2 (SP2)是MSXML 4.0和MSXML 4.0 Service Pack 1 (SP1)的完全取代版本亮穩(wěn)。它提供了大量的安全和程序錯誤修復(fù)。
  MSXML 4.0 SP2并不能取代MSXML 3.0,因為它已不再支持一些舊的以及不一致的功能。所質(zhì)肥否掌權(quán)塊破以用戶可能必須同時運行MSX嚴(yán)以合終屋業(yè)飯換ML 4.0和MSXML 3.0或更前版本。安裝Nero 8時要安裝最新版本MSXML 4.0,按正常的安裝就可以了對你的電腦沒有多大的影響


MSXML 4.0 Service Pack 2

單機百萬連接調(diào)優(yōu)

準(zhǔn)備兩臺Linux服務(wù)器,一個充當(dāng)服務(wù)端,一個充當(dāng)客戶端。

服務(wù)端

**作系統(tǒng):CentOS 7配置:4核8GIP:192.168.118.138

客戶端

**作系統(tǒng):CentOS 7配置:4核8GIP:192.168.118.139

服務(wù)端和客戶端均要配置java環(huán)境,基于jdk1.8。

如何模擬百萬連接#

如果服務(wù)端只開一個端口,客戶端連接的時候,端口號是有數(shù)量限制的(非root用戶,從1024到65535,大約6w),所以服務(wù)端開啟一個端口,客戶端和服務(wù)端的連接最多6w個左右。

為了模擬單機百萬連接,我們在服務(wù)端開啟多個端口,例如8000~8100,一共100個端口,客戶端還是6w的連接,但是可以連接服務(wù)端的不同端口,所以就可以模擬服務(wù)端百萬連接的情況。

準(zhǔn)備服務(wù)端程序#

服務(wù)端程序的主要邏輯是:

綁定8000端口一直到8099端口,一共100個端口,每2s鐘統(tǒng)計一下連接數(shù)。

channelActive觸發(fā)的時候,連接+1, channelInactive觸發(fā)的時候,連接-1。

代碼見:Server.java

準(zhǔn)備客戶端程序#

客戶端程序的主要邏輯是:

循環(huán)連接服務(wù)端的端口(從8000一直到8099)。

代碼見:Client.java

準(zhǔn)備好客戶端和服務(wù)端的代碼后,打包成Client.jar和Server.jar并上傳到客戶端和服務(wù)端的/data/app目錄下。打包配置參考pom.xml

服務(wù)端和客戶端在/data/app下分別準(zhǔn)備兩個啟動腳本,其中服務(wù)端準(zhǔn)備的腳本為startServer.sh, 客戶端準(zhǔn)備的腳本為startClient.sh,內(nèi)容如下:

startServer.sh

java -jar server.jar -Xms6.5g -Xmx6.5g -XX:NewSize=5.5g -XX:MaxNewSize=5.5g -XX:MaxDirectMemorySize=1g

startClient.sh

java -jar client.jar -Xms6.5g -Xmx6.5g -XX:NewSize=5.5g -XX:MaxNewSize=5.5g -XX:MaxDirectMemorySize=1g

腳本文件見:startServer.sh 和 startClient.sh

先啟動服務(wù)端

cd /data/app/

./startServer.sh

查看日志,待服務(wù)端把100個端口都綁定好以后。

在啟動客戶端

cd /data/app/

./startClient.sh

第二查看服務(wù)端日志,服務(wù)端在支撐了3942個端口號以后,報了如下錯誤:

Caused by: java.io.IOException: Too many open files
at sun.nio.ch.FileDispatcherImpl.init(Native Method)
at sun.nio.ch.FileDispatcherImpl.<clinit>(FileDispatcherImpl.java:35)
突破局部文件句柄限制#

使用ulimit -n命令可以查看一個jvm進程最多可以打開的文件個數(shù),這個是局部文件句柄限制,默認(rèn)是1024,我們可以修改這個值

vi /etc/security/limits.conf

增加如下兩行

* hard nofile 1000000
* soft nofile 1000000

以上配置表示每個進程可以打開的最大文件數(shù)是一百萬。

突破全局文件句柄限制#

除了突破局部文件句柄數(shù)限制,還需要突破全局文件句柄數(shù)限制,修改如下配置文件

vi /proc/sys/fs/file-max

將這個數(shù)量修改為一百萬

echo 1000000 > /proc/sys/fs/file-max

通過這種方式修改的配置在重啟后失效,如果要使重啟也生效,需要修改如下配置

vi /etc/sysctl.conf

在文件末尾加上

fs.file-max=1000000

服務(wù)端和客戶端在調(diào)整完局部文件句柄限制和全局文件句柄限制后,再次啟動服務(wù)端,待端口綁定完畢后,啟動客戶端。

查看服務(wù)端日志,可以看到,服務(wù)端單機連接數(shù)已經(jīng)達到百萬級別。

…..
connections: 434703
connections: 438238
connections: 441195
connections: 444082
connections: 447596
…..
connections: 920435
connections: 920437
connections: 920439
connections: 920442
connections: 920443
connections: 920445
…..

Netty應(yīng)用級別調(diào)優(yōu)#場景#

服務(wù)端接受到客戶端的數(shù)據(jù),進行一些相對耗時的**作(比如數(shù)據(jù)庫查詢,數(shù)據(jù)處理),第二把結(jié)果返回給客戶端。

模擬耗時**作#

在服務(wù)端,模擬通過sleep方法來模擬耗時**作,規(guī)則如下:

在90.0%情況下,處理時間為1ms在95.0%情況下,處理時間為10ms在99.0%情況下,處理時間為100ms在99.9%情況下,處理時間為1000ms

代碼如下

protected Object getResult(ByteBuf data) {
int level = ThreadLocalRandom.current().nextInt(1, 1000);
int time;
if (level <= 900) {
time = 1;
} else if (level <= 950) {
time = 10;
} else if (level <= 990) {
time = 100;
} else {
time = 1000;
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
return data;
}
客戶端統(tǒng)計QPS和AVG邏輯#

獲取當(dāng)前時間戳,客戶端在和服務(wù)端建立連接后,會每隔1s給服務(wù)端發(fā)送數(shù)據(jù),發(fā)送的數(shù)據(jù)就是當(dāng)前的時間戳,服務(wù)端獲取到這個時間戳以后,會把這個時間戳再次返回給客戶端,所以客戶端會拿到發(fā)送時候的時間戳,第二客戶端用當(dāng)前時間減去收到的時間戳,就是這個數(shù)據(jù)包的處理時間,記錄下這個時間,第二統(tǒng)計數(shù)據(jù)包發(fā)送的次數(shù),根據(jù)這兩個變量,可以求出QPS和AVG,其中:

QPS 等于

客戶端源碼參考:Client.java

服務(wù)端源碼參考:Server.java

服務(wù)端在不做任何優(yōu)化的情況下,關(guān)鍵代碼如下


bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));
ch.pipeline().addLast(/*businessGroup,*/ ServerBusinessHandler.INSTANCE);
// ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);
}
});

@ChannelHandler.Sharable
public class ServerBusinessHandler extends SimpleChannelInboundHandler<ByteBuf> {
public static final ChannelHandler INSTANCE = new ServerBusinessHandler();

@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
ByteBuf data = Unpooled.directBuffer();
data.writeBytes(msg);
Object result = getResult(data);
ctx.channel().writeAndFlush(result);
}

protected Object getResult(ByteBuf data) {
int level = ThreadLocalRandom.current().nextInt(1, 1000);
int time;
if (level <= 900) {
time = 1;
} else if (level <= 950) {
time = 10;
} else if (level <= 990) {
time = 100;
} else {
time = 1000;
}

try {
Thread.sleep(time);
} catch (InterruptedException e) {
}

return data;
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// ignore
}
}

運行服務(wù)端和客戶端,查看客戶端日志

…..
qps: 1466, avg response time: 35.68182
qps: 832, avg response time: 214.28384
qps: 932, avg response time: 352.59363
qps: 965, avg response time: 384.59448
qps: 957, avg response time: 403.33804
qps: 958, avg response time: 424.5246
qps: 966, avg response time: 433.35272
qps: 980, avg response time: 484.2116
qps: 986, avg response time: 478.5395
…..
優(yōu)化方案一:使用自定義線程池處理耗時邏輯#

將服務(wù)端代碼做如下調(diào)整

bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));
//ch.pipeline().addLast(/*businessGroup,*/ ServerBusinessHandler.INSTANCE);
ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);
}
});

其中ServerBusinessThreadPoolHandler中,使用了自定義的線程池來處理耗時的getResult方法。關(guān)鍵代碼如下:

private static ExecutorService threadPool = Executors.newFixedThreadPool(1000);
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
ByteBuf data = Unpooled.directBuffer();
data.writeBytes(msg);
threadPool.submit(() -> {
Object result = getResult(data);
ctx.channel().writeAndFlush(result);
});

}

再次運行服務(wù)端和客戶端,可以查看客戶端日志,QPS和AVG指標(biāo)都有明顯的改善

….
qps: 1033, avg response time: 17.690498
qps: 1018, avg response time: 17.133448
qps: 1013, avg response time: 15.563113
qps: 1010, avg response time: 15.415672
qps: 1009, avg response time: 16.049961
qps: 1008, avg response time: 16.179882
qps: 1007, avg response time: 16.120466
qps: 1006, avg response time: 15.822202
qps: 1006, avg response time: 15.987518
….

實際生產(chǎn)過程中,Executors.newFixedThreadPool(1000);中配置的數(shù)量需要通過壓測來驗證。

優(yōu)化方案二:使用Netty原生的線程池優(yōu)化#

我們可以通過Netty提供的線程池來處理耗時的Handler,這樣的話,無需調(diào)整Handler的邏輯(對原有Handler無代碼侵入),關(guān)鍵代碼:

bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new FixedLengthFrameDecoder(Long.BYTES));
// ch.pipeline().addLast(ServerBusinessHandler.INSTANCE);
// 使用業(yè)務(wù)線程池方式
// ch.pipeline().addLast(ServerBusinessThreadPoolHandler.INSTANCE);
// 使用Netty自帶線程池方式
ch.pipeline().addLast(businessGroup,ServerBusinessHandler.INSTANCE);
}
});

其中businessGroup是Netty自帶的線程池

EventLoopGroup businessGroup = new NioEventLoopGroup(1000);

ServerBusinessHandler中的所有方法,都會在businessGroup中執(zhí)行。

再次啟動服務(wù)端和客戶端,查看客戶端日志

…..
qps: 1027, avg response time: 23.833092
qps: 1017, avg response time: 20.98855
qps: 1014, avg response time: 18.220013
qps: 1012, avg response time: 17.447332
qps: 1010, avg response time: 16.502508
qps: 1010, avg response time: 15.692251
qps: 1009, avg response time: 15.968423
qps: 1008, avg response time: 15.888149
…..更多優(yōu)化建議#

參考Netty性能調(diào)優(yōu)奇技淫巧還有其他的嗎?

1.如果QPS過高,數(shù)據(jù)傳輸過快的情況下,調(diào)用writeAndFlush可以考慮拆分成多次write,第二單次flush,也就是批量flush**作

2.分配和釋放內(nèi)存盡量在reactor線程內(nèi)部做,這樣內(nèi)存就都可以在reactor線程內(nèi)部管理

3.盡量使用堆外內(nèi)存,盡量減少內(nèi)存的copy**作,使用CompositeByteBuf可以將多個ByteBuf組合到一起讀寫

4.外部線程連續(xù)調(diào)用eventLoop的異步調(diào)用方法的時候,可以考慮把這些**作封裝成一個task,提交到eventLoop,這樣就不用多次跨線程

5.盡量調(diào)用ChannelHandlerContext.writeXXX()方法而不是channel.writeXXX()方法,前者可以減少pipeline的遍歷

6.如果一個ChannelHandler無數(shù)據(jù)共享,那么可以搞成單例模式,標(biāo)注@Shareable,節(jié)省對象開銷對象

7.如果要做網(wǎng)絡(luò)**類似的功能,盡量復(fù)用eventLoop,可以避免跨reactor線程

拓展知識:

原創(chuàng)文章,作者:九賢生活小編,如若轉(zhuǎn)載,請注明出處:http://m.cxzzxj.cn/39415.html

少妇激情无码av| 欧XXXX欧洲| 无码一区二区免费波多野播放搜索 | 丁香五月91| 色欲aⅴ亚洲情无码AV| 亚洲AV大乳天堂在线观看| 午夜视频一区二区三区| 六月婷婷开心中文字| 欧美少妇一区| 国产精品免费一区二区| 欧美图库一区| 一区二区三区波多野结衣| 一区二区三区亚洲中文| 五月亚洲伊人| 超级碰碰碰97免费视频| 日韩精品欧美在线成人| 亚洲无码aaaa| 视频一区在线看| 久久五月丁香合缴情网| 久久爱www久久做| 国产日产欧毛片| 无码任你躁久久久久久久| 五月丁香啪啪综合缴情尤物| 阿娇囗交高潮种子| 日韩视频在线观看第二页| 经典鲁鲁国产在线视频在线看片| 欧美特一级| 国产十久久| 久久道无码| 欧美成人电影综合网站色www| 被操国产| 亚洲一区二区三区爽爽爽| 国产大全国产综合精品女同| 日韩高清免费大片| 无码中文字幕av免费放dvd| 亚洲国产中文精品看片在线观看| 久久人人爽中字视频| 踪合欧美激清| 亚洲熟妇码一区二区三区| 亚洲,欧美,日韩,国产,综合| 国产精品密桃久久|