-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1653 lines (735 loc) · 79.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html class="theme-next mist use-motion">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />
<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />
<meta name="keywords" content="Hexo, NexT" />
<link rel="alternate" href="/atom.xml" title="YiHao's Blog" type="application/atom+xml" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />
<meta property="og:type" content="website">
<meta property="og:title" content="YiHao's Blog">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="YiHao's Blog">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="YiHao's Blog">
<script type="text/javascript" id="hexo.configuration">
var NexT = window.NexT || {};
var CONFIG = {
scheme: 'Mist',
sidebar: {"position":"left","display":"post"},
fancybox: true,
motion: true,
duoshuo: {
userId: 0,
author: 'Author'
}
};
</script>
<link rel="canonical" href="http://yoursite.com/"/>
<title>
Hexo, NexT - YiHao's Blog -
</title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="default">
<div class="container one-collumn sidebar-position-left
page-home
">
<div class="headband"></div>
<!------add Fork me on Github------->
<a href="https://github.com/yihaoDeng"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">YiHao's Blog</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle"></p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br />
Homepage
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
Archives
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
Tags
</a>
</li>
<li class="menu-item menu-item-guestbook">
<a href="/guestbook" rel="section">
<i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br />
contact
</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/02/临时启动一个http-Server传送文件/" itemprop="url">
临时启动一个http Server传送文件
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-09-02T17:40:31+08:00" content="2016-09-02">
2016-09-02
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/09/02/临时启动一个http-Server传送文件/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/09/02/临时启动一个http-Server传送文件/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h4 id="查看端口有没有使用:"><a href="#查看端口有没有使用:" class="headerlink" title="查看端口有没有使用:"></a>查看端口有没有使用:</h4><p>可以没有这一步,这里只是确认一下你预服务的端口没有被其他服务占用</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">netstat -natpl|grep 端口号</div></pre></td></tr></table></figure>
<h4 id="目标机打开个http服务:"><a href="#目标机打开个http服务:" class="headerlink" title="目标机打开个http服务:"></a>目标机打开个http服务:</h4><p>有些机器上会出现<code>No module named SimpleHTTPServe</code>, 重新装python吧! 在python 3.x 中, </p>
<p>在 python 2.x 中 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">python -m SimpleHTTPServe port</div></pre></td></tr></table></figure>
<p>在 python 3.x 中 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">python -m http.server port</div></pre></td></tr></table></figure>
<h4 id="接收机下载文件:"><a href="#接收机下载文件:" class="headerlink" title="接收机下载文件:"></a>接收机下载文件:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">wget http://目标机ip:端口号/文件名(wget限速:wget --limit-rate=nM)</div></pre></td></tr></table></figure>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/09/02/ansible小试牛刀/" itemprop="url">
ansible小试牛刀
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-09-02T17:21:22+08:00" content="2016-09-02">
2016-09-02
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/09/02/ansible小试牛刀/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/09/02/ansible小试牛刀/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>1 先产生本地公钥<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">ssh-keygen -t rsa</div></pre></td></tr></table></figure></p>
<p>2 公钥拷贝到到到各个机器上</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">ssh-copy-id -i ~/.ssh/id_rsa.pub hostnam</div></pre></td></tr></table></figure>
<p>3 然后设置ansible 配置文件</p>
<p> 在/etc/ansible文件下 分别创建文件hosts 和ansible.cfg(如果没有该文件夹ansible,自行创建)</p>
<p><strong>在hosts进行相应分组</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">[group1]</div><div class="line">hostname1</div><div class="line">hostname2</div><div class="line">[group2]</div><div class="line">hostnamex</div><div class="line">hostnamey</div></pre></td></tr></table></figure></p>
<p><strong>在ansible.cfg 文件中填写一些默认配置</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">[defaults]</div><div class="line">host_key_checking = False</div><div class="line"></div><div class="line">sudo_user = root</div><div class="line"></div><div class="line">remote_user = 远程机器上你默认的用户名</div></pre></td></tr></table></figure></p>
<p>如果在想在远程用root 执行命令, 则可以把hosts配置成这样,<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">[group1]</div><div class="line">xxx.xxx.xxx.xxx ansible_ssh_user=test ansible_ssh_pass=xxx ansible_su_pass=xxxxx</div><div class="line">xxx.xxx.xxx.xxx ansible_ssh_user=test ansible_ssh_pass=xxx ansible_su_pass=xxxxx</div><div class="line">xxx.xxx.xxx.xxx ansible_ssh_user=test ansible_ssh_pass=xxx ansible_su_pass=xxxxxx</div></pre></td></tr></table></figure></p>
<p>4 测试是否能用</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">ansible group1 -a 'who' // 用配置文件默认的用户在远程机器上执行命令 `who`</div><div class="line">ansible group2 -a 'who' --sudo --ask-sudo-pass // 用root 身份执行 `who`</div><div class="line"></div><div class="line">ansible group1 -m copy -a "src=/Users/fdafda/test.txt dest=/usr/local/" --sudo --ask-sudo-pass // 把本地文件拷贝到group1机器下的/usr/local文件下</div></pre></td></tr></table></figure>
<p>5 对于涉及过程比较多远程执行, 可以用ansible-playbook<br> <strong>编写playbook.yml 文件, 试例如下:</strong><br> <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">- hosts: group1</div><div class="line"> become: yes</div><div class="line">become_user: root</div><div class="line">tasks:</div><div class="line"> - name: updatefile</div><div class="line"> shell: wget xxxxx/idgen/idgen_s</div><div class="line"> register: out1</div><div class="line"> - debug: msg="{{ out1.stdout }}"</div><div class="line"> -</div></pre></td></tr></table></figure></p>
<p> 执行该命令</p>
<p> <strong>然后执行如下命令</strong></p>
<pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">ansible-playbook playbook.yml</div></pre></td></tr></table></figure>
</code></pre>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/07/07/读取文件,出现了编码错误/" itemprop="url">
读取文件,出现了编码错误
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-07-07T19:07:18+08:00" content="2016-07-07">
2016-07-07
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/07/07/读取文件,出现了编码错误/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/07/07/读取文件,出现了编码错误/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<blockquote>
<p> 用scala读取本地文本文件, 出现了错误, 特此记录</p>
</blockquote>
<ul>
<li>源程序</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">import scala.io.Source</div><div class="line">Source.fromFile("logExample.txt").foreach(print)</div></pre></td></tr></table></figure>
<ul>
<li><p>错误现象</p>
<p>文本在打印过程中出现下面的错误输出 </p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">java.nio.charset.MalformedInputException: Input length = 1</div><div class="line">at java.nio.charset.CoderResult.throwException(CoderResult.java:277)</div><div class="line">at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:337)</div><div class="line">at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)</div><div class="line">at java.io.InputStreamReader.read(InputStreamReader.java:184)</div><div class="line">at java.io.BufferedReader.fill(BufferedReader.java:153)</div><div class="line">at java.io.BufferedReader.read(BufferedReader.java:174)</div><div class="line">``` </div><div class="line">- 解决方法</div><div class="line"> </div><div class="line"> 貌似好多人在平时开发中也遇到这样的错误,网上也有各种解决方法。有人尝试这样的解决方法, 貌似有人居然也解决了问题,初步猜想是,默认编码方式错误。</div></pre></td></tr></table></figure>
<p> import scala.io.Source<br> Source.fromFile(“logExample.txt”)(“UTF-8”).foreach(print)<br> <figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">通用的的解决方法</div><div class="line"></div><div class="line">**解决思路**: 检测出illegal UTF-8 byte sequence, 然后替换掉。 由于中文字符使用3个字节或者4个,所以可能被分开, 导致读取失败</div></pre></td></tr></table></figure></p>
<pre><code> import scala.io.Source
import scala.io.Codec
import java.nio.charset.CodingErrorAction
...
</code></pre><p> implicit val codec = Codec(“UTF-8”)<br> codec.onMalformedInput(CodingErrorAction.REPLACE)<br> codec.onUnmappableCharacter(CodingErrorAction.REPLACE)<br> Source.fromFile(“logExample.txt”).foreach(print)</p>
<p> ```</p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/07/04/tiker与其他channel公用时问题/" itemprop="url">
tiker与其他channel共用时问题
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-07-04T16:38:34+08:00" content="2016-07-04">
2016-07-04
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/07/04/tiker与其他channel公用时问题/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/07/04/tiker与其他channel公用时问题/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h4 id="ticker与其他channel共用时的问题"><a href="#ticker与其他channel共用时的问题" class="headerlink" title="ticker与其他channel共用时的问题"></a>ticker与其他channel共用时的问题</h4><p>见代码</p>
<figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> (</div><div class="line"> <span class="string">"fmt"</span></div><div class="line"> <span class="string">"runtime"</span></div><div class="line"> <span class="string">"time"</span></div><div class="line">)</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">init</span><span class="params">()</span></span> {</div><div class="line"> runtime.GOMAXPROCS(runtime.NumCPU())</div><div class="line"></div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</div><div class="line"> ch := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">int</span>, <span class="number">1024</span>)</div><div class="line"></div><div class="line"> <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">(ch <span class="keyword">chan</span> <span class="keyword">int</span>)</span></span> {</div><div class="line"> <span class="keyword">for</span> {</div><div class="line"> val := <-ch</div><div class="line"> fmt.Printf(<span class="string">"val:%d\n"</span>, val)</div><div class="line"> }</div><div class="line"> }(ch)</div><div class="line"> tick := time.NewTicker(<span class="number">1</span> * time.Second)</div><div class="line"> <span class="keyword">for</span> i := <span class="number">0</span>; i < <span class="number">20</span>; i++ {</div><div class="line"> <span class="keyword">select</span> {</div><div class="line"> <span class="keyword">case</span> ch <- i:</div><div class="line"> <span class="keyword">case</span> <-tick.C:</div><div class="line"> fmt.Printf(<span class="string">"%d: case <-tick.C\n"</span>, i)</div><div class="line"> }</div><div class="line"> time.Sleep(<span class="number">200</span> * time.Millisecond)</div><div class="line"> }</div><div class="line"> <span class="built_in">close</span>(ch)</div><div class="line"> tick.Stop()</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure>
<h4 id="代码结果"><a href="#代码结果" class="headerlink" title="代码结果"></a>代码结果</h4><figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">val:<span class="number">0</span></div><div class="line">val:<span class="number">1</span></div><div class="line">val:<span class="number">2</span></div><div class="line">val:<span class="number">3</span></div><div class="line">val:<span class="number">4</span></div><div class="line">val:<span class="number">5</span></div><div class="line">val:<span class="number">6</span></div><div class="line">val:<span class="number">7</span></div><div class="line">val:<span class="number">8</span></div><div class="line">val:<span class="number">9</span></div><div class="line"><span class="number">10</span>: <span class="keyword">case</span> <-tick.C</div><div class="line">val:<span class="number">11</span></div><div class="line">val:<span class="number">12</span></div><div class="line">val:<span class="number">13</span></div><div class="line">val:<span class="number">14</span></div><div class="line">val:<span class="number">15</span></div><div class="line"><span class="number">16</span>: <span class="keyword">case</span> <-tick.C</div><div class="line">val:<span class="number">17</span></div><div class="line">val:<span class="number">18</span></div><div class="line">val:<span class="number">19</span></div></pre></td></tr></table></figure>
<p>从结果中可以看出,作者本意是要输出0~19, 却不想被打断..</p>
<h4 id="出现问题的代码"><a href="#出现问题的代码" class="headerlink" title="出现问题的代码"></a>出现问题的代码</h4><figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> {</div><div class="line"><span class="keyword">case</span> ch <- i:</div><div class="line"><span class="keyword">case</span> <-tick.C:</div><div class="line"> fmt.Printf(<span class="string">"%d: case <-tick.C\n"</span>, i)</div><div class="line">}</div></pre></td></tr></table></figure>
<blockquote>
<p>注意: 当两个case条件都满足的时候,运行时系统会通过一个伪随机的算法决定哪个case将会被执行<br>所以当tick.C条件满足的那个循环,有某种概率造成ch<-i没有发送(虽然通道两端没有阻塞,满足发送条件)</p>
</blockquote>
<h4 id="解决方案一"><a href="#解决方案一" class="headerlink" title="解决方案一"></a>解决方案一</h4><p>一旦tick.C随机的case被随机到,就多执行一次ch<-i, 很显然,这个方法比较牵强,而且在i比较多的时候,很麻烦, 所以pass</p>
<figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> {</div><div class="line"> <span class="keyword">case</span> ch <- i:</div><div class="line"> <span class="keyword">case</span> <-tick.C:</div><div class="line"> fmt.Printf(<span class="string">"%d: case <-tick.C\n"</span>, i)</div><div class="line"> ch <- i</div><div class="line">}</div></pre></td></tr></table></figure>
<h4 id="解决方法二"><a href="#解决方法二" class="headerlink" title="解决方法二"></a>解决方法二</h4><p>将tick.C的case单独放到一个select里面,并加入一个default(保证不阻塞), 这种处理方法就优雅的多。(这是参考网友的思路)<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">select {</div><div class="line">case ch <- i:</div><div class="line">}</div><div class="line">select {</div><div class="line">case <-tick.C:</div><div class="line"> fmt.Printf("%d: case <-tick.C\n", i)</div><div class="line"> default:</div><div class="line">}</div></pre></td></tr></table></figure></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/07/04/golang超时处理/" itemprop="url">
golang超时处理
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-07-04T14:52:54+08:00" content="2016-07-04">
2016-07-04
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/07/04/golang超时处理/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/07/04/golang超时处理/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p> 超时对于程序操作外部资源或者管理自身程序执行时间非常重要。在 Go 语言中,因为channel与select,所以实现超时非常容易与优雅。</p>
<h4 id="案例程序一"><a href="#案例程序一" class="headerlink" title="案例程序一"></a>案例程序一</h4><figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> main</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"time"</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="string">"fmt"</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</div><div class="line"> c1 := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">string</span>)</div><div class="line"> <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</div><div class="line"> time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line"> c1 <- <span class="string">"result 1"</span></div><div class="line"></div><div class="line"> }()</div><div class="line"></div><div class="line"> <span class="keyword">select</span> {</div><div class="line"></div><div class="line"> <span class="keyword">case</span> res := <-c1:</div><div class="line"></div><div class="line"> fmt.Println(res)</div><div class="line"></div><div class="line"> <span class="keyword">case</span> <-time.After(time.Second * <span class="number">1</span>):</div><div class="line"></div><div class="line"> fmt.Println(<span class="string">"timeout 1"</span>)</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line"> c2 := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">string</span>)</div><div class="line"></div><div class="line"> <span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> {</div><div class="line"></div><div class="line"> time.Sleep(time.Second * <span class="number">2</span>)</div><div class="line"></div><div class="line"> c2 <- <span class="string">"result 2"</span></div><div class="line"></div><div class="line"> }()</div><div class="line"></div><div class="line"> <span class="keyword">select</span> {</div><div class="line"></div><div class="line"> <span class="keyword">case</span> res := <-c2:</div><div class="line"></div><div class="line"> fmt.Println(res)</div><div class="line"></div><div class="line"> <span class="keyword">case</span> <-time.After(time.Second * <span class="number">3</span>):</div><div class="line"></div><div class="line"> fmt.Println(<span class="string">"timeout 2"</span>)</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line">}</div></pre></td></tr></table></figure>
<h4 id="运行结果"><a href="#运行结果" class="headerlink" title="运行结果"></a>运行结果</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">timeout 1</div><div class="line"></div><div class="line">result 2</div></pre></td></tr></table></figure>
<h4 id="程序分析"><a href="#程序分析" class="headerlink" title="程序分析"></a>程序分析</h4><p>分析结果:主程序首先阻塞在 select中,如果在time.second <em> 1内收不到channel 发送过来的信号, 由于groutine 睡眠了time.second </em> 2了, 则select 超时,下面的程序也是按照这个逻辑运行。</p>
<h4 id="案例程序二"><a href="#案例程序二" class="headerlink" title="案例程序二"></a>案例程序二</h4><figure class="highlight golang"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">fmt.Println(<span class="string">"hello"</span>)</div><div class="line"><-time.After(<span class="number">2</span> * time.Second)</div><div class="line">fmt.Println(<span class="string">"world"</span>)</div></pre></td></tr></table></figure>
<h4 id="程序运行结果"><a href="#程序运行结果" class="headerlink" title="程序运行结果"></a>程序运行结果</h4><p>程序首先打印出 hello, 间隔 2*time.Second 后打印出world。</p>
<h4 id="结果分析"><a href="#结果分析" class="headerlink" title="结果分析"></a>结果分析</h4><p>如果把<-time.After(2 <em> time.Second)改成 time.After(2 </em> time.Second),则 程序会立刻打印出hello及world</p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/07/04/golang的byte和int之间的转换/" itemprop="url">
golang的byte和int之间的转换
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-07-04T14:47:12+08:00" content="2016-07-04">
2016-07-04
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/07/04/golang的byte和int之间的转换/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/07/04/golang的byte和int之间的转换/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>golang的byte 和int的转换</p>
<p>在使用golang做数据传输的时候,会经常遇到byte与int的互转,但golang并没有现成的方法,因此只能通过binary包来解决<br>所以,需要 :<code>import “encoding/binary”</code>,又因为是byte的转换,所以还涉及到了bytes:<code>import “bytes”</code></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">package main</div><div class="line"></div><div class="line">import (</div><div class="line"> "bytes"</div><div class="line"> "encoding/binary"</div><div class="line"> "fmt"</div><div class="line"> "strings"</div><div class="line">)</div><div class="line"></div><div class="line">func main() {</div><div class="line"> b := []byte{0x00, 0x00, 0x03, 0xe8}</div><div class="line"> b_buf := bytes.NewBuffer(b)</div><div class="line"> var x int32</div><div class="line"> binary.Read(b_buf, binary.BigEndian, &x)</div><div class="line"> fmt.Println(x)</div><div class="line"></div><div class="line"> fmt.Println(strings.Repeat("-", 100)) // string的一个函数</div><div class="line"></div><div class="line"> x = 1000</div><div class="line"> b_buf = bytes.NewBuffer([]byte{}) // 可以直接为空进行初始化,</div><div class="line"> binary.Write(b_buf, binary.BigEndian, x)</div><div class="line"> fmt.Println(b_buf.Bytes())</div><div class="line">}</div></pre></td></tr></table></figure>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2016/07/04/time-wait过多分析/" itemprop="url">
time_wait过多分析
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time itemprop="dateCreated" datetime="2016-07-04T11:48:34+08:00" content="2016-07-04">
2016-07-04
</time>
</span>
<span class="post-comments-count">
|
<a href="/2016/07/04/time-wait过多分析/#comments" itemprop="discussionUrl">
<span class="post-comments-count ds-thread-count" data-thread-key="2016/07/04/time-wait过多分析/" itemprop="commentsCount"></span>
</a>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<blockquote>
<p> 最近DBA发现Atlas和mysql之间存在大量处于time-waiter状态的connect,。 这个现象很不合理,因为Atlas是复用connect, 也就是说:当前端有一个请求过来的时候, Atlas会在当前线程的连接池中取一个可用连接,并且在处理完该请求后,会把该connect放回到连接池中,当然对于需要维持session的请求(事务、在server端处理的prepare()),只有当客户显式调用close的时候,才会把该connect放回到连接池中。因此想找找原因, 之前觉得对`time_wait` 理解的还行,但具体过程也淡忘了, 之后看到了某作者写的这篇文章, 觉得写的挺详细的, 特别转载以方便以后查询。</p>
</blockquote>
<p>[转载文章如下]</p>
<p><strong>TIME_WAIT的产生原因</strong></p>
<p>因为TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭;后发FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留两倍的<br><a href="http://en.wikipedia.org/wiki/Maximum_Segment_Lifetime" target="_blank" rel="external">MSL</a>时长。</p>
<p><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/3675218771011332995.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-2cf093f636d180b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="3675218771011332995"></a></p>
<p>MSL指的是报文段的最大生存时间,如果报文段在网络活动了MSL时间,还没有被接收,那么会被丢弃。关于MSL的大小,<a href="http://tools.ietf.org/search/rfc793" target="_blank" rel="external">RFC 793</a>协议中给出的建议是两分钟,不过实际上不同的操作系统可能有不同的设置,以Linux为例,通常是半分钟,两倍的MSL就是一分钟,也就是60秒,并且这个数值是硬编码在<a href="https://github.com/torvalds/linux/blob/master/include/net/tcp.h" target="_blank" rel="external">内核</a>中的,也就是说除非你重新编译内核,否则没法修改它。</p>
<p><strong>TIME_WAIT的产生原因</strong></p>
<p>因为TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭;后发FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留两倍的MSL时长。TIME_WAIT问题小结 – 网易杭州QA – 网易杭州 QA TeamMSL指的是报文段的最大生存时间,如果报文段在网络活动了MSL时间,还没有被接收,那么会被丢弃。关于MSL的大小,RFC 793协议中给出的建议是两分钟,不过实际上不同的操作系统可能有不同的设置,以Linux为例,通常是半分钟,两倍的MSL就是一分钟,也就是60秒,并且这个数值是硬编码在内核中的,也就是说除非你重新编译内核,否则没法修改它。TIME_WAIT状态存在的必要性。为什么主动关闭的一端不直接进入closed状态,而是要先进入time_wait并且停留两倍的MSL时长呢?这是因为TCP是建立在不可靠网络上的可靠协议。如果主动关闭的一端收到被动关闭一端的发出的FIN包后,返回ACK包,同时进入TIME_WAIT,但是由于网络的原因,主动关闭一端发送的ACK包可能会延迟,从而触发被动关闭一方重传FIN包,这样一来一回极端情况正好是2MSL。如果主动关闭的一端直接close或者不到两倍MSL时间就关闭,那么被动关闭发出重传FIN包到达,可能出现的问题是:旧的连接不存在,系统只能返回RST包;新的TCP连接已经建立,延迟包可能会干扰新连接。这都可能导致TCP不可靠。</p>
<p><strong>TIME_WAIT过多的危害</strong></p>
<p>在生产过程中,如果服务器使用短连接,那么完成一次请求后会主动断开连接,就会造成大量time_wait状态。因此我们常常在系统中会采用长连接,减少建立连接的消耗,同时也减少TIME_WAIT的产生,但实际上即使使用长连接配置不当时,当TIME_WAIT的生产速度远大于其消耗速度时,系统仍然会累计大量的TIME_WAIT状态的连接。TIME_WAIT状态连接过多就会造成一些问题。如果客户端的TIME_WAIT连接过多,同时它还在不断产生,将会导致客户端端口耗尽,新的端口分配不出来,出现错误。如果服务器端的TIME_WAIT连接过多,可能会导致客户端的请求连接失败,这在接下来举例说明。</p>
<p><strong>TIME_WAIT**</strong>问题定位**</p>
<p><strong>案例一:</strong></p>
<p>将nginx作为反向代理时,后连tomcat等服务器。测试中不同并发压力下多次、反复出现nginx服务器端口资源耗尽的问题。表现为nginx服务器出现大量time_wait状态连接,端口资源耗尽(nginx报错:cannot assign requested address )。首先检查nginx开启了长连接keepalive,但是系统仍然出现了大量的TIME_WAIT,这就和之前提到的当系统产生TIME_WAIT的速度大于其消耗速度时,就会累计TIME_WAIT。原因是:keepalive取配置太小,将其增大后问题得以解决。(PS:nginx总的keepalive连接池大小 = keepalive取值 * nginx worker数)</p>
<p><strong>案例二:</strong></p>
<p>某应用其中一层系统架构Nginx+Tomcat,客户端发出的请求为HTTP HEAD,客户端TPS有段时间接近为0,返回Connection time out错误。<br><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/6597301763611814346.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-a7019b821123b1c1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="6597301763611814346"></a></p>
<p>观察大部分错误请求响应时间刚好是30s,这正好是nginx的连接超时时间配置,Tomcat没有收到这些错误请求,这意味着请求Nginx连接Tomcat都没有成功。这是为什么呢?Tomcat的连接池不够用吗? 实际上Tomcat work线程不到200个,远小于MaxThread(1024)的值,同时还观察到Tomcat上的TIME_WAIT连接数量不正常,达到了近两万个。<br><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/736338539175571363.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-3b6513ad036215e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="736338539175571363"></a><br>系统是设置了长连接的,为什么还有这么多TIME_WAIT,难道长连接没有生效吗?<br>Nginx作为反向代理,长连接配置主要有三项,upstream中的keepalive设置单个worker最大请求数,参数proxy_http_version 1.1强制转换为http1.1协议(默认支持长连接),proxy_set_header Connection将请求头部connection为空(http1.0请求默认connection头部为close)<br>upstream backend_nosfs {<br>server 10.10.10.10:8185;<br>keepalive 1024;<br> keepalive_requests;<br>}<br>proxy_http_version 1.1;<br>proxy_set_header Connection “”;<br>Tomcat端增加配置maxKeepAliveRequests=“10000”,表示一个连接上最大请求数达到10000才会断开。<br>定位长连接问题,最简单直接的方法就是抓包,通过wireshark分析Nginx和Tomcat直接连接果然没有生效,一条连接只处理了一个请求。</p>
<p><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/796011234238224070.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-65b6b099d0c154e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="796011234238224070"></a></p>
<p>为什么设置了长连接相关的配置,还是没有生效呢?经过排查发现,proxy_http_version 1.1;<br>proxy_set_header Connection “”这两项配置放在Nginx的Http域中,实际上他们要放在server域才会生效,将其位置修改后,长连接生效了,所有问题都解决了。但是我们不禁会尝试疑问TIME_WAIT出现在Tomcat而不是在Nginx上?从抓包可以看出Nginx发送给Tomcat包头部Connection为close,所以Tomcat在处理完head请求后就主动关闭,所以TIME_WAIT出现在Tomcat服务器。 配置修改后,问题解决了,TPS也上去了,之前出现的连接失败问题也没有了。<br><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/3196992785579897494.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-61f87a3264e0372f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="3196992785579897494"></a></p>
<p>但是为什么Tomcat服务器上的TIME_WAIT过多会导致Nginx连接失败呢?理论上说,服务器只监听在一个端口,但是会new出很多socket去处理请求,难道是socket不够用吗?再观察资源使用发现虽然TIME_WAIT连接数多,但是句柄数并不多,而socket的数量是受制于句柄数。那真正的原因是什么呢?在系统TIME_WAIT较多时,Dmesg系统出错日志为:</p>
<p><strong>nf_conntrack: table full, dropping packet</strong></p>
<p>真相大白了,Conntrack表用于记录每个连接的状态,在tcp协议中用源ip/port+目的ip/port唯一标识一个连接。记录TCP连接状态的表满了导致请求失败。查看系统ip_contrack_max配置为65536,在极端的情况下超出了其配置所有导致连接失败。<br><a href="http://www.zuoqin.me/wp-content/uploads/2015/08/1808476725466247815.png" target="_blank" rel="external"><img src="http://upload-images.jianshu.io/upload_images/1968185-8f50d819fd54826d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="1808476725466247815"></a><br><strong>如何控制TIME_WAIT**</strong>的数量**</p>
<p>通过以上的TIME_WAIT问题,我们可以看到TIME_WAIT这个状态不存在不行,但是过多就对系统会造成困扰。那么我们应该如何控制TIME_WAIT的数量呢?</p>
<p><strong>长连接</strong></p>
<p>对于反向代理和应用服务器,最好是要配置成支持keepalive长连接,否则在系统并发增加时会导致一系列的连接问题。对于nginx+tomcat长连接的配置前面有一些介绍可以参考,其它服务器一般也是提供支持长连接配置的,设置后建议抓包测试验证。<br>一般来说长连接设置正确了TIME_WAIT数量不会暴涨,但是长连接最大请求数也是有效的,但如果应用的处理速度很快导致TIME_WAIT的产生的速度远快于TIME_WAIT的消耗速度时系统就会累计TIME_WAIT状态连接。这时候可能就要修改一些系统配置了。</p>
<p><strong>ip_conntrack</strong></p>