рд╣рдордиреЗ GO рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ DNS рд╕рд░реНрд╡рд░ рдХреЛ рдХреИрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛

рдкрд╛рдареНрдпрдХреНрд░рдо рдкрд░ рдПрдХ рдирдИ рдзрд╛рд░рд╛ рдХреА рд╢реБрд░реБрдЖрдд рдХреА рдкреНрд░рддреНрдпрд╛рд╢рд╛ рдореЗрдВ "рдбреЗрд╡рд▓рдкрд░ рдЧреЛрд▓рдВрдЧ" рдиреЗ рджрд┐рд▓рдЪрд╕реНрдк рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЕрдиреБрд╡рд╛рдж рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред




рд╣рдорд╛рд░реЗ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ DNS рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдЬрд╛рд░реЛрдВ рд╡реЗрдмрд╕рд╛рдЗрдЯреЛрдВ рдХреЗ рджрд╕рд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдкреНрд░рддрд┐рджрд┐рди рд▓рд╛рдЦреЛрдВ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЙрддреНрддрд░ рджреЗрддреЗ рд╣реИрдВред рдЖрдЬрдХрд▓, рдбреАрдПрдирдПрд╕ рд╣рдорд▓реЗ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрддреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рдбреАрдПрдирдПрд╕ рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЙрдЪреНрдЪ рднрд╛рд░ рдХреЗ рддрд╣рдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

dnsflood рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЯреВрд▓ рд╣реИ рдЬреЛ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ udp рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдЬреЗрдирд░реЗрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

# timeout 20s ./dnsflood example.com 127.0.0.1 -p 2053

рд╕рд┐рд╕реНрдЯрдо рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХрд╛ рдореЗрдореЛрд░реА рдЙрдкрдпреЛрдЧ рдЗрддрдиреА рддреЗрдЬреА рд╕реЗ рдмрдврд╝рд╛ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рд░реЛрдХрдирд╛ рдкрдбрд╝рд╛, рдЕрдиреНрдпрдерд╛ рд╣рдо OOM рддреНрд░реБрдЯрд┐рдпреЛрдВ рдореЗрдВ рднрд╛рдЧ рдЬрд╛рддреЗред рдпрд╣ рдореЗрдореЛрд░реА рд▓реАрдХ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреА рддрд░рд╣ рдерд╛; "рд╕рдорд╛рди" рдФрд░ "рд╡рд╛рд╕реНрддрд╡рд┐рдХ" рдореЗрдореЛрд░реА рд▓реАрдХ рд╣реЛрдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░рдг рд╣реИрдВ:

  • рд▓рдЯрдХреЗ рд╣реБрдП рдЧреЛрд░реЛрдЪрди
  • рдбреЗрдлрд░ рдФрд░ рдлрд╛рдЗрдирд▓ рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ
  • рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рд╕рдм-рдХрдЯреНрд╕
  • рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ рдЪрд░

рдпрд╣ рдкреЛрд╕реНрдЯ рд╡рд┐рднрд┐рдиреНрди рд▓реАрдХ рдХрд╛ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИред

рдХрд┐рд╕реА рднреА рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЛ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдкрд╣рд▓реЗ рдПрдХ рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ рдХрд░реЗрдВред

Godebug


рд╡рд┐рднрд┐рдиреНрди рдбрд┐рдмрдЧрд┐рдВрдЧ рдЯреВрд▓ рдХреЛ рдПрдХ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ GODEBUG, рдЬреЛ рдХрд┐ рдЬреЛрдбрд╝реЛрдВ рдХреЗ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рд╕реЗ рдЕрд▓рдЧ рдХреА рдЧрдИ рд╕реВрдЪреА рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВ name=valueред

рдЯреНрд░реЗрд╕ рдкреНрд▓рд╛рдирд░


рдЕрдиреБрд╕реВрдЪрдХ рдЯреНрд░реЗрд╕ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЧреЛрд░реЛрдЗрди рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╢реЗрдбреНрдпреВрд▓рд░ рдЯреНрд░реЗрд╕ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдЪрд▓рд╛рдПрдВ GODEBUG=schedtrace=100, рдорд╛рди ms рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдЕрд╡рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред

$ GODEBUG=schedtrace=100 ./redins -c config.json
SCHED 2952ms: ... runqueue=3 [26 11 7 18 13 30 6 3 24 25 11 0]
SCHED 3053ms: ... runqueue=3 [0 0 0 0 0 0 0 0 4 0 21 0]
SCHED 3154ms: ... runqueue=0 [0 6 2 4 0 30 0 5 0 11 2 5]
SCHED 3255ms: ... runqueue=1 [0 0 0 0 0 0 0 0 0 0 0 0]
SCHED 3355ms: ... runqueue=0 [1 0 0 0 0 0 0 0 0 0 0 0]
SCHED 3456ms: ... runqueue=0 [0 0 0 0 0 0 0 0 0 0 0 0]
SCHED 3557ms: ... runqueue=0 [13 0 3 0 3 33 2 0 10 8 10 14]
SCHED 3657ms: ...runqueue=3 [14 1 0 5 19 54 9 1 0 1 29 0]
SCHED 3758ms: ... runqueue=0 [67 1 5 0 0 1 0 0 87 4 0 0]
SCHED 3859ms: ... runqueue=6 [0 0 3 6 0 0 0 0 3 2 2 19]
SCHED 3960ms: ... runqueue=0 [0 0 1 0 1 0 0 1 0 1 0 0]
SCHED 4060ms: ... runqueue=5 [4 0 5 0 1 0 0 0 0 0 0 0]
SCHED 4161ms: ... runqueue=0 [0 0 0 0 0 0 0 1 0 0 0 0]
SCHED 4262ms: ... runqueue=4 [0 128 21 172 1 19 8 2 43 5 139 37]
SCHED 4362ms: ... runqueue=0 [0 0 0 0 0 0 0 0 0 0 0 0]
SCHED 4463ms: ... runqueue=6 [0 28 23 39 4 11 4 11 25 0 25 0]
SCHED 4564ms: ... runqueue=354 [51 45 33 32 15 20 8 7 5 42 6 0]

runqueue рдЧреЛрд░реЛрдирд╛рдЗрдЯреНрд╕ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрд╢реНрд╡рд┐рдХ рдХрддрд╛рд░ рдХреА рд▓рдВрдмрд╛рдИ рд╣реИред рдХреЛрд╖реНрдардХ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрддрд╛рд░ рдХреА рд▓рдВрдмрд╛рдИ рд╣реИред

рдЖрджрд░реНрд╢ рд╕реНрдерд┐рддрд┐ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рд╕рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдЧреЛрд░реЛрдЗрдЯрд┐рди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╡реНрдпрд╕реНрдд рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХрддрд╛рд░ рдХреА рдордзреНрдпрдо рд▓рдВрдмрд╛рдИ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рднреА рдХреЗ рд▓рд┐рдП рд╡рд┐рддрд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ:

SCHED 2449ms: gomaxprocs=12 idleprocs=0 threads=40 spinningthreads=1 idlethreads=1 runqueue=20 [20 20 20 20 20 20 20 20 20 20 20]

рдЕрдиреБрд╕реВрдЪреА рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП , рд╣рдо рд╕рдордп рдХреА рдЕрд╡рдзрд┐ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рд▓рдЧрднрдЧ рд╕рднреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдмреЗрдХрд╛рд░ рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдкреВрд░реА рдХреНрд╖рдорддрд╛ рд╕реЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдХрдЪрд░рд╛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЯреНрд░реЗрд╕


рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг (GC) рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рдПрдВ GODEBUG=gctrace=1:

GODEBUG=gctrace=1 ./redins -c config1.json
.
.
.
gc 30 @3.727s 1%: 0.066+21+0.093 ms clock, 0.79+128/59/0+1.1 ms cpu, 67->71->45 MB, 76 MB goal, 12 P
gc 31 @3.784s 2%: 0.030+27+0.053 ms clock, 0.36+177/81/7.8+0.63 ms cpu, 79->84->55 MB, 90 MB goal, 12 P
gc 32 @3.858s 3%: 0.026+34+0.024 ms clock, 0.32+234/104/0+0.29 ms cpu, 96->100->65 MB, 110 MB goal, 12 P
gc 33 @3.954s 3%: 0.026+44+0.13 ms clock, 0.32+191/131/57+1.6 ms cpu, 117->123->79 MB, 131 MB goal, 12 P
gc 34 @4.077s 4%: 0.010+53+0.024 ms clock, 0.12+241/159/69+0.29 ms cpu, 142->147->91 MB, 158 MB goal, 12 P
gc 35 @4.228s 5%: 0.017+61+0.12 ms clock, 0.20+296/179/94+1.5 ms cpu, 166->174->105 MB, 182 MB goal, 12 P
gc 36 @4.391s 6%: 0.017+73+0.086 ms clock, 0.21+492/216/4.0+1.0 ms cpu, 191->198->122 MB, 210 MB goal, 12 P
gc 37 @4.590s 7%: 0.049+85+0.095 ms clock, 0.59+618/253/0+1.1 ms cpu, 222->230->140 MB, 244 MB goal, 12 P
.
.
.

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдпрд╣рд╛рдВ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕реНрдореГрддрд┐ рдХреА рдорд╛рддреНрд░рд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИ, рдФрд░ рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреАрд╕реА рдХреА рдорд╛рддреНрд░рд╛ рднреА рдмрдврд╝ рдЬрд╛рддреА рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЬрд┐рддрдирд╛ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЙрд╕рд╕реЗ рдЕрдзрд┐рдХ рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдЖрдк рдпрд╣рд╛рдВGODEBUG рдХреБрдЫ рдФрд░ рдЧреЛрд▓рд╛рдВрдЧ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рдЪрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ ред

рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛


go tool pprof- рдбреЗрдЯрд╛ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдгред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ pprof: рдпрд╛ рддреЛ runtime/pprofрдЖрдкрдХреЗ рдХреЛрдб рдореЗрдВ рд╕реАрдзреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ , рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП pprof.StartCPUProfile(), рдпрд╛ рдПрдХ net/http/pprofhttp рд╕реВрдЪреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рдЬреЛ рд╣рдордиреЗ рдХрд┐рдпрд╛ рдерд╛ред рдЗрд╕рдХреА pprofрдмрд╣реБрдд рдХрдо рд╕рдВрд╕рд╛рдзрди рдЦрдкрдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░реЛрдлрд╛рдЗрд▓ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдбреЗрдЯрд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреЗрд╡рд▓ "рдиреЗрдЯ / http / pprof" рдкреИрдХреЗрдЬ рдЖрдпрд╛рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ :

import (
  _ "net/http/pprof"
)

рдлрд┐рд░ рдПрдХ http рд╕реВрдЪреА рдЬреЛрдбрд╝реЗрдВ:

go func() {
  log.Println(http.ListenAndServe("localhost:6060", nil))
}()

Pprof рдореЗрдВ рдХрдИ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╣реИрдВ:

  • allocs : рд╕рднреА рдкрд┐рдЫрд▓реЗ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
  • рдмреНрд▓реЙрдХ : рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдкреНрд░рд╛рдЗрдореЗрдЯреАрдЬ рдЕрд╡рд░реБрджреНрдз рд╣реЛ рдЧрдпрд╛
  • рдЧреЛрд░реЛрдЗрди : рд╕рднреА рдореМрдЬреВрджрд╛ рдЧреЛрд░реЛрдЗрдиреНрдЯреНрд╕ рдХрд╛ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕
  • рдвреЗрд░ : рдЬреАрд╡рд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
  • рдореНрдпреВрдЯреЗрдХреНрд╕ : рдкрд░рд╕реНрдкрд░ рд╡рд┐рд░реЛрдзреА рдореНрдпреВрдЯреЗрдХреНрд╕ рдзрд╛рд░рдХреЛрдВ рдХрд╛ рдвреЗрд░
  • рдкреНрд░реЛрдлрд╛рдЗрд▓ : рдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░реЛрдлрд╛рдЗрд▓ред
  • рдереНрд░реЗрдбрдХреНрд░реИрдЯ : рдПрдХ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕, рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдУрдПрд╕ рдореЗрдВ рдирдП рдереНрд░реЗрдбреНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реБрдЖ
  • рдЯреНрд░реЗрд╕ : рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗред

рдиреЛрдЯ: рдЕрдиреНрдп рд╕рднреА рд╕рдорд╛рдкрди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд рдЯреНрд░реЗрд╕ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ, рдПрдХ рдЯреНрд░реЗрд╕ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╣реИ , рди рдХрд┐ рдирд┐рдЬреА рддреМрд░ рдкрд░ , рдЖрдк рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЧреЛ рдЯреВрд▓ рдЯреНрд░реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ go tool pprofред
рдЕрдм рдЬрдм рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдЙрдкрд▓рдмреНрдз рд╕рд╛рдзрдиреЛрдВ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░


тАНтАНтАНтАНтАНтАНтАНтАНтАНтАНтАНтАНтАНтАНтАН$ go tool pprof http://localhost:6060/debug/pprof/profile?seconds=10


рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ 30 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рд╣рдо рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕реЗрдЯ рдХрд░рдХреЗ рдЗрд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ seconds) рдФрд░ рдкреНрд░рддреНрдпреЗрдХ 100 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреЗ рдирдореВрдиреЗ рдПрдХрддреНрд░ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдпрд╣ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдореЛрдб рдореЗрдВ рдЬрд╛рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЖрдо рдЖрджреЗрд╢реЛрдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ top, list, webред рдкрд╛рда рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╕рдмрд╕реЗ рдЧрд░реНрдо рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП

рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ top n, -cumрд╕рдВрдЪрдпреА рдХреНрд░рдо рдХреЗ рд▓рд┐рдП рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдЫрд╛рдВрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рднреА рджреЛ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ рдФрд░ -flatред

(pprof) top 10 -cum
Showing nodes accounting for 1.50s, 6.19% of 24.23s total
Dropped 347 nodes (cum <= 0.12s)
Showing top 10 nodes out of 186
flat  flat%   sum%  cum   cum%
0.03s 0.12% 0.12% 16.7s 69.13% (*Server).serveUDPPacket
0.05s 0.21% 0.33% 15.6s 64.51% (*Server).serveDNS
0     0%    0.33% 14.3s 59.10% (*ServeMux).ServeDNS
0     0%    0.33% 14.2s 58.73% HandlerFunc.ServeDNS
0.01s 0.04% 0.37% 14.2s 58.73% main.handleRequest
0.07s 0.29% 0.66% 13.5s 56.00% (*DnsRequestHandler).HandleRequest
0.99s 4.09% 4.75% 7.56s 31.20% runtime.gentraceback
0.02s 0.08% 4.83% 7.02s 28.97% runtime.systemstack
0.31s 1.28% 6.11% 6.62s 27.32% runtime.mallocgc
0.02s 0.08% 6.19% 6.35s 26.21% (*DnsRequestHandler).FindANAME
(pprof)

listрдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

(pprof) list handleRequest
Total: 24.23s
ROUTINE ======================== main.handleRequest in /home/arash/go/src/arvancloud/redins/redins.go
     10ms     14.23s (flat, cum) 58.73% of Total
        .          .     35: l          *handler.RateLimiter
        .          .     36: configFile string
        .          .     37:)
        .          .     38:
        .          .     39:func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
     10ms      610ms     40: context := handler.NewRequestContext(w, r)
        .       50ms     41: logger.Default.Debugf("handle request: [%d] %s %s", r.Id, context.RawName(), context.Type())
        .          .     42:
        .          .     43: if l.CanHandle(context.IP()) {
        .     13.57s     44:  h.HandleRequest(context)
        .          .     45: } else {
        .          .     46:  context.Response(dns.RcodeRefused)
        .          .     47: }
        .          .     48:}
        .          .     49:
(pprof)

рдЯреАрдо webрдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдПрдХ рдПрд╕рд╡реАрдЬреА-рдЧреНрд░рд╛рдл рдЙрддреНрдкрдиреНрди рдХрд░рддреА рд╣реИ рдФрд░ рдЗрд╕реЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЦреЛрд▓рддреА рд╣реИред

(pprof)web handleReques



рдЬреАрд╕реА рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рд╕рдордп рдХреА рдПрдХ рдмрдбрд╝реА рд░рд╛рд╢рд┐ рдЦрд░реНрдЪ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ runtime.mallocgcрдЕрдХреНрд╕рд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдХрдЪрд░рд╛ рдХрд▓реЗрдХреНрдЯрд░ рдХреЛ рд▓реЛрдб рдЬреЛрдбрд╝ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╡рд┐рд▓рдВрдмрддрд╛ рдмрдврд╝рд╛ рд╕рдХрддрд╛ рд╣реИред

рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдореИрдХреЗрдирд┐рдЬреНрдо рдкрд░ рдЦрд░реНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╕рдордп рдХреА рдПрдХ рдмрдбрд╝реА рд░рд╛рд╢рд┐, рдЬреИрд╕реЗ рдХрд┐ runtime.chansendрдпрд╛ runtime.lock, рд╕рдВрдШрд░реНрд╖ рдХрд╛ рд╕рдВрдХреЗрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд╕рдордп рдХреА рдПрдХ рдмрдбрд╝реА рд░рд╛рд╢рд┐ рдЦрд░реНрдЪ syscall.Read/WriteрдЖрдИ / рдУ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдЕрддреНрдпрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд╛ рдорддрд▓рдм рд╣реИред

рдореЗрдореЛрд░реА рдкреНрд░реЛрдлрд╛рдЗрд▓рд░


$ go tool pprof http://localhost:6060/debug/pprof/allocs


рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдпрд╣ рдЖрдмрдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рд╣рдо -alloc_objectsрдЕрдиреНрдп рдЙрдкрдпреЛрдЧреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрдпрдирд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ : -iuse_objectsрдФрд░ рд▓рд╛рдЗрд╡ рдореЗрдореЛрд░реА рдХреА -inuse_spaceрдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП ред рдЖрдорддреМрд░ рдкрд░, рдпрджрд┐ рдЖрдк рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдХрдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ , рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рд╡рд┐рд▓рдВрдмрддрд╛ рдХреЛ рдХрдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкрд░реНрдпрд╛рдкреНрдд рд░рди рдпрд╛ рд▓реЛрдб рд╕рдордп рдХреЗ рдмрд╛рдж рджреЗрдЦреЗрдВред

-inuse_space-alloc_objects

рдЕрдбрд╝рдЪрди рдХреА рдкрд╣рдЪрд╛рди


рдкрд╣рд▓реЗ рдЕрдбрд╝рдЪрди рдХреЗ рдкреНрд░рдХрд╛рд░ (рдкреНрд░реЛрд╕реЗрд╕рд░, рдЖрдИ / рдУ, рдореЗрдореЛрд░реА) рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдЬреЛ рд╣рдо рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдкреНрд░реЛрдлрд╛рдЗрд▓рд░реНрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЯреВрд▓ рд╣реИред

go tool traceрджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧреЛрд░реЛрдЗрдЯрд┐рди рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдХреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рдЯреНрд░реЗрд╕ рдЙрджрд╛рд╣рд░рдг рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЯреНрд░реЗрд╕ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдкрд░ рдПрдХ HTTP рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

$ curl http://localhost:6060/debug/pprof/trace?seconds=5 --output trace.out

рдЯреНрд░реЗрд╕ рдХрд┐рдП рдЧрдП рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрддреНрдкрдиреНрди рдлрд╝рд╛рдЗрд▓ рджреЗрдЦреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:

$ go tool trace trace.out
2019/12/25 15:30:50 Parsing trace...
2019/12/25 15:30:59 Splitting trace...
2019/12/25 15:31:10 Opening browser. Trace viewer is listening on http://127.0.0.1:42703

Go рдЯреВрд▓ рдЯреНрд░реЗрд╕ рдПрдХ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ Chrome DevTools рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ Chrome рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИред рдореБрдЦреНрдп рдкреГрд╖реНрда рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдЯреНрд░реЗрд╕ рджреЗрдЦреЗрдВ (0s-409.575266ms)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (411.075559ms-747.252311ms)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (747.252311ms-1.234962645s)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (1.234968945s-1.774245108s) - 1.776/424
рджреЗрдЦреЗрдВред
рдЯреНрд░реЗрд╕
рджреЗрдЦреЗрдВ (2.111339514s-2.674030898s)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (2.674031362s-3.044145798s)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (3.044145798s-3.458795252s)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (3.43953778s-4.075080634s)
рд╡реНрдпреВ рдЯреНрд░реЗрд╕ (4.07508109898) 4.4278s -4.814869651s)
рдЯреНрд░реЗрд╕ рджреЗрдЦреЗрдВ (4.814869651s-5.253597835s)

рдЧреЛрд░реЛрдЗрди рд╡рд┐рд╢реНрд▓реЗрд╖рдг
рдиреЗрдЯрд╡рд░реНрдХ рдЕрд╡рд░реБрджреНрдз рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ ()
рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдмреНрд▓реЙрдХрд┐рдВрдЧ рдкреНрд░реЛрдлрд╛рдЗрд▓ ()
Syscall рдЕрд╡рд░реБрджреНрдз рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ ()
рд╢реЗрдбреНрдпреВрд▓рд░ рд╡рд┐рд▓рдВрдмрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ ()
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд╛рд░реНрдп
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреНрд╖реЗрддреНрд░
рдиреНрдпреВрдирддрдо рдЙрддреНрдкрд░рд┐рд╡рд░реНрддреА рдЙрдкрдпреЛрдЧ

рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдЯреНрд░реЗрд╕ рд╕рдордп рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдкрдХрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХреЗред



рдпрд╣рд╛рдВ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реИ, рдЬреЛ рдЙрдиреНрд╣реЗрдВ рд▓рдЧрднрдЧ рдЕрдкрдардиреАрдп рдмрдирд╛рддрд╛ рд╣реИ рдпрджрд┐ред рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рджреЗрдЦ рд░рд╣реЗ рд╣реИрдВред рдЪрд▓реЛ рдЕрдм рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЫреЛрдбрд╝ рджреЗрдВред

рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд┐рдВрдХ "рдЧреЛрд░реЛрдЗрди рд╡рд┐рд╢реНрд▓реЗрд╖рдг" рд╣реИ , рдЬреЛ рдЯреНрд░реЗрд╕ рдЕрд╡рдзрд┐ рдХреЗ рджреМрд░рд╛рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЧреЛрд░реЛрдЗрдЯрд┐рди рджрд┐рдЦрд╛рддрд╛ рд╣реИ:

Goroutines:
github.com/miekg/dns.(*Server).serveUDPPacket N=441703
runtime.gcBgMarkWorker N=12
github.com/karlseguin/ccache.(*Cache).worker N=2
main.Start.func1 N=1
runtime.bgsweep N=1
arvancloud/redins/handler.NewHandler.func2 N=1
runtime/trace.Start.func1 N=1
net/http.(*conn).serve N=1
runtime.timerproc N=3
net/http.(*connReader).backgroundRead N=1
N=40

рдПрди = 441703 рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ , рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:


рдЧреЛрд░реЛрдЯрд┐рди рд╡рд┐рд╢реНрд▓реЗрд╖рдг

рдпрд╣ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред рдЕрдзрд┐рдХрд╛рдВрд╢ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЛ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдореЗрдВ рд▓рдЧрднрдЧ рдХреЛрдИ рд╕рдордп рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдЬреНрдпрд╛рджрд╛рддрд░ рд╕рдордп рд╕рд┐рдВрдХ рдмреНрд▓реЙрдХ рдореЗрдВ рдЦрд░реНрдЪ рд╣реЛрддрд╛ рд╣реИред рдЖрдЗрдП рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


рдЧреЛрд░реЛрдЗрди рдЯреНрд░реЗрд╕ рдкреИрдЯрд░реНрди

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реИред рдпрд╣рд╛рдВ рд╕реЗ рд╣рдо рд╕реАрдзреЗ рд▓реЙрдХ рдЯреВрд▓ рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ; рд▓реЙрдХ рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо рд╣реИ, рд╣рдореЗрдВ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

runtime.SetBlockProfileRate(1)

рдЕрдм рд╣рдо рддрд╛рд▓реЗ рдХрд╛ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

$ go tool pprof http://localhost:6060/debug/pprof/block
(pprof) top
Showing nodes accounting for 16.03wks, 99.75% of 16.07wks total
Dropped 87 nodes (cum <= 0.08wks)
Showing top 10 nodes out of 27
     flat  flat%   sum%        cum   cum%
 10.78wks 67.08% 67.08%   10.78wks 67.08%  internal/poll.(*fdMutex).rwlock
  5.25wks 32.67% 99.75%    5.25wks 32.67%  sync.(*Mutex).Lock
        0     0% 99.75%    5.25wks 32.67%  arvancloud/redins/handler.(*DnsRequestHandler).Filter
        0     0% 99.75%    5.25wks 32.68%  arvancloud/redins/handler.(*DnsRequestHandler).FindANAME
        0     0% 99.75%   16.04wks 99.81%  arvancloud/redins/handler.(*DnsRequestHandler).HandleRequest
        0     0% 99.75%   10.78wks 67.08%  arvancloud/redins/handler.(*DnsRequestHandler).Response
        0     0% 99.75%   10.78wks 67.08%  arvancloud/redins/handler.(*RequestContext).Response
        0     0% 99.75%    5.25wks 32.67%  arvancloud/redins/handler.ChooseIp
        0     0% 99.75%   16.04wks 99.81%  github.com/miekg/dns.(*ServeMux).ServeDNS
        0     0% 99.75%   16.04wks 99.81%  github.com/miekg/dns.(*Server).serveDNS
(pprof)

рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд╛рд▓реЗ рд╣реИрдВ ( рдкреЛрд▓.рдлреАрдбрдореНрдпреВрдЯреЗрдХреНрд╕ рдФрд░ рд╕рд┐рдВрдХ.рдореНрдпреВрдЯреЗрдХреНрд╕ ), рд▓рдЧрднрдЧ 100% рддрд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ред рдпрд╣ рд▓реЙрдХ рд╕рдВрдШрд░реНрд╖ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдорд╛рд░реА рдзрд╛рд░рдгрд╛ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ, рдЕрдм рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХрд╣рд╛рдВ рд╣реЛрддрд╛ рд╣реИ:

(pprof) svg lock

рдпрд╣ рдХрдорд╛рдВрдб рдмреНрд▓реЙрдХрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдкрд░ рдЬреЛрд░ рджреЗрдиреЗ рдХреЗ рд╕рд╛рде рд╕рднреА рд╕рдВрдШрд░реНрд╖ рдХреЗ рдкреНрд░рддрд┐ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдиреЛрдбреНрд╕ рдХрд╛ рдПрдХ рд╡реЗрдХреНрдЯрд░ рдЧреНрд░рд╛рдл рдмрдирд╛рддрд╛ рд╣реИ:


рдмреНрд▓реЙрдХрд┐рдВрдЧ рдПрдВрдбрдкреЙрдЗрдВрдЯ

рдХреЗ svg- рдЧреНрд░рд╛рдл рд╣рдо рдЧреЛрд░реЛрдЗрди рдПрдВрдбрдкреЙрдЗрдВрдЯ рд╕реЗ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

$ go tool pprof http://localhost:6060/debug/pprof/goroutine

рдФрд░ рдлрд┐рд░:

(pprof) top
Showing nodes accounting for 294412, 100% of 294424 total
Dropped 84 nodes (cum <= 1472)
Showing top 10 nodes out of 32
     flat  flat%   sum%        cum   cum%
   294404   100%   100%     294404   100%  runtime.gopark
        8 0.0027%   100%     294405   100%  github.com/miekg/dns.(*Server).serveUDPPacket
        0     0%   100%      58257 19.79%  arvancloud/redins/handler.(*DnsRequestHandler).Filter
        0     0%   100%      58259 19.79%  arvancloud/redins/handler.(*DnsRequestHandler).FindANAME
        0     0%   100%     293852 99.81%  arvancloud/redins/handler.(*DnsRequestHandler).HandleRequest
        0     0%   100%     235406 79.95%  arvancloud/redins/handler.(*DnsRequestHandler).Response
        0     0%   100%     235406 79.95%  arvancloud/redins/handler.(*RequestContext).Response
        0     0%   100%      58140 19.75%  arvancloud/redins/handler.ChooseIp
        0     0%   100%     293852 99.81%  github.com/miekg/dns.(*ServeMux).ServeDNS
        0     0%   100%     293900 99.82%  github.com/miekg/dns.(*Server).serveDNS
(pprof)

рд╣рдорд╛рд░реЗ рд▓рдЧрднрдЧ рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд░рдо рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИрдВред рдЧреЛрдкрд╛рд░реНрдХ, рдпрд╣ рдПрдХ рдЧреЛ рд╢реЗрдбреНрдпреВрд▓рд░ рд╣реИ рдЬреЛ рдЧреЛрд░реЛрдЗрдЯрд┐рди рд╕реЛрддрд╛ рд╣реИ; рдЗрд╕рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░рдг рдПрдХ рддрд╛рд▓рд╛ рд╕рдВрдШрд░реНрд╖ рд╣реИ

(pprof) svg gopark


рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдЧреЛрд░реЛрдЗрди рдХреЗ svg- рдЧреНрд░рд╛рдл

рдпрд╣рд╛рдБ рд╣рдо рд╕рдВрдШрд░реНрд╖ рдХреЗ рджреЛ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:

UDPConn.WriteMsg ()


рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рднреА рдЙрддреНрддрд░ рдПрдХ рд╣реА рдПрдлрдбреА (рдЗрд╕рд▓рд┐рдП рд▓реЙрдХ) рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЗрд╕рд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рднреА рдПрдХ рд╣реА рд╕реНрд░реЛрдд рдХрд╛ рдкрддрд╛ рд╣реИред

рд╣рдордиреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛, рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдордиреЗ рд▓реЛрдб рдХреЛ рд╕рдВрддреБрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╢реНрд░реЛрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдУрдПрд╕ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЗ рдмреАрдЪ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрддреБрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрдШрд░реНрд╖реЛрдВ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред

рд░реИрдВрдб ()


рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣рд╛рдБ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЧрдгрд┐рдд / рд░реИрдВрдб рдХрд╛рд░реНрдп (рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдореЗрдВ рдПрдХ рддрд╛рд▓рд╛ рд╣реИ рдпрд╣рд╛рдБ )ред рдпрд╣ Rand.New()рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЬрдирд░реЗрдЯрд░ рдХреА рдорджрдж рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдЖрд╡рд░рдг рдмрдирд╛рддрд╛ рд╣реИред

rg := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))

рдпрд╣ рдереЛрдбрд╝рд╛ рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ рд╕реНрд░реЛрдд рдмрдирд╛рдирд╛ рдорд╣рдВрдЧрд╛ рд╣реИред рдХреНрдпрд╛ рдпрд╣ рдмреЗрд╣рддрд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдореЗрдВ рд▓реЛрдб рдХреЛ рд╕рдВрддреБрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди рд╡рд┐рддрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ Time.Nanoseconds()рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЕрдм рдЬрдм рд╣рдордиреЗ рд╕рднреА рдЕрдирд╛рд╡рд╢реНрдпрдХ рддрд╛рд▓реЗ рд╣рдЯрд╛ рджрд┐рдП рд╣реИрдВ, рддреЛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рджреЗрдЦреЗрдВ:


рдЧреЛрд░реЛрдиреЗрдЯрд┐рди рд╡рд┐рд╢реНрд▓реЗрд╖рдг

рдмреЗрд╣рддрд░ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓реЙрдХ рдХрд░рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдЖрдЗрдП рдЯреНрд░реЗрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдореБрдЦреНрдп рдкреГрд╖реНрда рд╕реЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓реЙрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓реЙрдХ рдЯрд╛рдЗрдорд▓рд╛рдЗрди

рдЪрд▓реЛ ccacheрд▓реЙрдХ рдПрдВрдбрдкреЙрдЗрдВрдЯ рд╕реЗ рдмреВрд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ pprof:

(pprof) list promote
ROUTINE ======================== github.com/karlseguin/ccache.(*Cache).promote in ...
        0   9.66days (flat, cum) 99.70% of Total
        .          .    155: h.Write([]byte(key))
        .          .    156: return c.buckets[h.Sum32()&c.bucketMask]
        .          .    157:}
        .          .    158:
        .          .    159:func (c *Cache) promote(item *Item) {
        .   9.66days    160: c.promotables <- item
        .          .    161:}
        .          .    162:
        .          .    163:func (c *Cache) worker() {
        .          .    164: defer close(c.donec)
        .          .    165:

рд╕рднреА рдХреЙрд▓ ccache.Get()рдПрдХ рдЪреИрдирд▓ рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрддреА рд╣реИрдВ c.promotablesред рдХреИрд╢рд┐рдВрдЧ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рд╣рдореЗрдВ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП; рдореЗрдВ Dgraph рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓реЗрдЦ рд╣реИ рдХреИрд╢ рд░рд╛рдЬреНрдп! рдЬрд╛рдУ , рд╡реЗ рднреА рдЙрддреНрдХреГрд╖реНрдЯ рдХреИрд╢рд┐рдВрдЧ рдореЙрдбреНрдпреВрд▓ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ristretto ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд░рд┐рд╕реНрдЯреНрд░реЗрдЯреЛ рдЕрднреА рддрдХ рдЯреАрдЯреАрдПрд▓-рдЖрдзрд╛рд░рд┐рдд рд░рд┐рд▓реАрдЬрд╝ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╣рдо рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд▓рдЧрднрдЧ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ MaxCostрдФрд░ рдЕрдкрдиреА рдХреИрд╢ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдЯрд╛рдЗрдордЖрдЙрдЯ рдореВрд▓реНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рдо рдХреИрд╢ рдореЗрдВ рдкреБрд░рд╛рдирд╛ рдбреЗрдЯрд╛ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ)ред рдЖрдЗрдП


рд░рд┐рд╕реНрдЯреНрд░реЗрдЯреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВ: рдЧреЛрд░рдЖрдЙрдЯ рд╡рд┐рд╢реНрд▓реЗрд╖рдг

рдЧреНрд░реЗрдЯ!

рд╣рдо gorutin рдХреЗ рдЕрдзрд┐рдХрддрдо рд░рдирдЯрд╛рдЗрдо рдХреЛ 5000 ms рд╕реЗ рдШрдЯрд╛рдХрд░ 22 ms рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп "рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓реЙрдХ" рдФрд░ "рд╢реЗрдбреНрдпреВрд▓рд░ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛" рдХреЗ рдмреАрдЪ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рд▓реЙрдХ рдЯрд╛рдЗрдорд▓рд╛рдЗрди

рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ fdMutex.rwlock, рдЕрдм рд╣рдо рджреВрд╕рд░реЗ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ: gcMarkDone, рдЬреЛ рдмреНрд▓реЙрдХ рд╕рдордп рдХреЗ 53% рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рдореЗрдВ рдЙрдирдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдЕрдХреНрд╕рд░ рдПрдХ рд╕рдВрдХреЗрдд рд╣реИ рдХрд┐ рд╣рдо рдЬреАрд╕реА рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдЖрд╡рдВрдЯрди рдЕрдиреБрдХреВрд▓рди


рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдпрд╣ рджреЗрдЦрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ; рдЧреЛ, рдорд╛рд░реНрдХ-рдПрдВрдб-рд╕реНрд╡реАрдк рдкрд┐рдХрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЙрди рд╕рднреА рдЪреАрдЬрд╝реЛрдВ рдкрд░ рдирдЬрд╝рд░ рд░рдЦрддрд╛ рд╣реИ, рдЬреЛ рдЪрдпрдирд┐рдд рд╣реИрдВ, рдФрд░ рдЬреИрд╕реЗ рд╣реА рдпрд╣ рдЖрдХрд╛рд░ рд╕реЗ рджреЛрдЧреБрдирд╛ (рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдореВрд▓реНрдп рдЬреЛ GOGC рдкрд░ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ) рдкрд┐рдЫрд▓реЗ рдЖрдХрд╛рд░ рдХреЗ рдЖрдХрд╛рд░ рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ рд╣реИ, GC рд╕рдлрд╛рдИ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИред рдореВрд▓реНрдпрд╛рдВрдХрди рддреАрди рдЪрд░рдгреЛрдВ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ:

  • рдорд╛рд░реНрдХрд░ рд╕реЗрдЯрд┐рдВрдЧ (STW)
  • рдЕрдВрдХрди (рд╕рдорд╛рдирд╛рдВрддрд░)
  • рд▓реЗрдмрд▓рд┐рдВрдЧ рдПрдВрдб (STW)

рд╕реНрдЯреЙрдк рдж рд╡рд░реНрд▓реНрдб (STW) рдЪрд░рдг рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реЗ рдЖрдорддреМрд░ рдкрд░ рдмрд╣реБрдд рдХрдо рд╣реЛрддреЗ рд╣реИрдВ, рдирд┐рд░рдВрддрд░ рдЪрдХреНрд░ рдЕрд╡рдзрд┐ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ (v1.13 рдкрд░ рдЬрд╛рдПрдВ) рдЧреЛрд░реЛрдЗрдВрдЯрд┐рди рдХреЛ рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЗ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рджрдмрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдПрдХ рд╕рддрдд рдЪрдХреНрд░ рдХреЗ рд▓рд┐рдП, рдПрдХ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд▓рдВрдмрд╛ рдард╣рд░рд╛рд╡ рд╕рдордп рд╕рдВрднрд╡ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЬреАрд╕реА рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЧреЛрд░реЛрдЗрдиреНрдЯреНрд╕ рдХреА рдЙрдореНрдореАрдж рд╣реИред

рдЕрдВрдХрди рдХреЗ рджреМрд░рд╛рди, рдЬреАрд╕реА рд▓рдЧрднрдЧ 25% рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ GOMAXPROCS, рд▓реЗрдХрд┐рди рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЬрдмрд░рди рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдорд╛рд░реНрдХ рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП , рдпрд╣ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рддреЗрдЬреА рд╕реЗ рдмрдврд╝рддреЗ рдЧреЛрд░реЛрдЗрди рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдорд╛рд░реНрдХрд░ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЬреАрд╕реА рдХреЗ рдХрд╛рд░рдг рджреЗрд░реА рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ, рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдХрдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рджреЛ рдмрд╛рддреЗрдВ:

  • рдЖрд╡рдВрдЯрди рдХреА рд╕рдВрдЦреНрдпрд╛ рдЖрдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 20-рдмрд╛рдЗрдЯ рд╕рдВрд░рдЪрдирд╛ рд╕реЗ 1000 рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди 20,000 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдПрдХрд▓ рдЖрд╡рдВрдЯрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдвреЗрд░ рдкрд░ рдЕрдзрд┐рдХ рднрд╛рд░ рдкреИрджрд╛ рдХрд░рддреЗ рд╣реИрдВ);
  • рд╕реА / рд╕реА ++ рдЬреИрд╕реА рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╕рднреА рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рдвреЗрд░ рдкрд░ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЧреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рддрдп рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╡реЗрд░рд┐рдПрдмрд▓ рд╣реАрдк рдореЗрдВ рдЬрд╛рдПрдЧрд╛ рдпрд╛ рд╕реНрдЯреИрдХ рдлреНрд░реЗрдо рдХреЗ рдЕрдВрджрд░ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдвреЗрд░ рдкрд░ рдЖрд╡рдВрдЯрд┐рдд рдЪрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдвреЗрд░ рдкрд░ рдЖрд╡рдВрдЯрд┐рдд рдЪрд░ рдЬреАрд╕реА рд▓реЛрдб рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рдЧреЛ рдореЗрдореЛрд░реА рдореЙрдбрд▓ рдФрд░ рдЬреАрд╕реА рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдкреНрд░рд╕реНрддреБрддрд┐ рдХреЛ рджреЗрдЦреЗрдВ ред

рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЯреВрд▓рдХрд┐рдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

  • рдЧрд░реНрдо рд╡рд┐рддрд░рдг рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░;
  • рдЯреНрд░реИрдХрд┐рдВрдЧ рдЖрд╡рдВрдЯрди рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдкреНрд░реЛрдлрд╛рдЗрд▓рд░;
  • рдкреИрдЯрд░реНрди рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЗрдЦрдХ; рдЬреАрд╕реА
  • рдЖрд╡рдВрдЯрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдкреНрд░реЛрд╕реЗрд╕рд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

$ go tool pprof http://localhost:6060/debug/pprof/profile?seconds=20
(pprof) top 20 -cum
Showing nodes accounting for 7.27s, 29.10% of 24.98s total
Dropped 315 nodes (cum <= 0.12s)
Showing top 20 nodes out of 201
     flat  flat%   sum%        cum   cum%
        0     0%     0%     16.42s 65.73%  github.com/miekg/dns.(*Server).serveUDPPacket
    0.02s  0.08%  0.08%     16.02s 64.13%  github.com/miekg/dns.(*Server).serveDNS
    0.02s  0.08%  0.16%     13.69s 54.80%  github.com/miekg/dns.(*ServeMux).ServeDNS
    0.01s  0.04%   0.2%     13.48s 53.96%  github.com/miekg/dns.HandlerFunc.ServeDNS
    0.02s  0.08%  0.28%     13.47s 53.92%  main.handleRequest
    0.24s  0.96%  1.24%     12.50s 50.04%  arvancloud/redins/handler.(*DnsRequestHandler).HandleRequest
    0.81s  3.24%  4.48%      6.91s 27.66%  runtime.gentraceback
    3.82s 15.29% 19.78%      5.48s 21.94%  syscall.Syscall
    0.02s  0.08% 19.86%      5.44s 21.78%  arvancloud/redins/handler.(*DnsRequestHandler).Response
    0.06s  0.24% 20.10%      5.25s 21.02%  arvancloud/redins/handler.(*RequestContext).Response
    0.03s  0.12% 20.22%      4.97s 19.90%  arvancloud/redins/handler.(*DnsRequestHandler).FindANAME
    0.56s  2.24% 22.46%      4.92s 19.70%  runtime.mallocgc
    0.07s  0.28% 22.74%      4.90s 19.62%  github.com/miekg/dns.(*response).WriteMsg
    0.04s  0.16% 22.90%      4.40s 17.61%  github.com/miekg/dns.(*response).Write
    0.01s  0.04% 22.94%      4.36s 17.45%  github.com/miekg/dns.WriteToSessionUDP
    1.43s  5.72% 28.66%      4.30s 17.21%  runtime.pcvalue
    0.01s  0.04% 28.70%      4.15s 16.61%  runtime.newstack
    0.06s  0.24% 28.94%      4.09s 16.37%  runtime.copystack
    0.01s  0.04% 28.98%      4.05s 16.21%  net.(*UDPConn).WriteMsgUDP
    0.03s  0.12% 29.10%      4.04s 16.17%  net.(*UDPConn).writeMsg

рд╣рдо рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, mallocgcрдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдорджрдж рдорд┐рд▓рддреА рд╣реИ

(pprof) svg mallocgc



рд╣рдо рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рддрд░рдг рдХреЛ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ alloc, рд╡рд┐рдХрд▓реНрдк рдХрд╛ alloc_objectрдЕрд░реНрде рд╣реИ рдЖрд╡рдВрдЯрди рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛, рд╕реНрдореГрддрд┐ рдФрд░ рдЖрд╡рдВрдЯрди рд╕реНрдерд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред

$ go tool pprof -alloc_objects http://localhost:6060/debug/pprof/allocs
(pprof) top -cum
Active filters:
  show=handler
Showing nodes accounting for 58464353, 59.78% of 97803168 total
Dropped 1 node (cum <= 489015)
Showing top 10 nodes out of 19
     flat  flat%   sum%        cum   cum%
 15401215 15.75% 15.75%   70279955 71.86%  arvancloud/redins/handler.(*DnsRequestHandler).HandleRequest
  2392100  2.45% 18.19%   27198697 27.81%  arvancloud/redins/handler.(*DnsRequestHandler).FindANAME
   711174  0.73% 18.92%   14936976 15.27%  arvancloud/redins/handler.(*DnsRequestHandler).Filter
        0     0% 18.92%   14161410 14.48%  arvancloud/redins/handler.(*DnsRequestHandler).Response
 14161410 14.48% 33.40%   14161410 14.48%  arvancloud/redins/handler.(*RequestContext).Response
  7284487  7.45% 40.85%   11118401 11.37%  arvancloud/redins/handler.NewRequestContext
 10439697 10.67% 51.52%   10439697 10.67%  arvancloud/redins/handler.reverseZone
        0     0% 51.52%   10371430 10.60%  arvancloud/redins/handler.(*DnsRequestHandler).FindZone
  2680723  2.74% 54.26%    8022046  8.20%  arvancloud/redins/handler.(*GeoIp).GetSameCountry
  5393547  5.51% 59.78%    5393547  5.51%  arvancloud/redins/handler.(*DnsRequestHandler).LoadLocation

рдЕрдм рд╕реЗ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рдЪреЗрдХ рдХрд░реЗрдВ:

рдкреНрд░рд┐рдВрдЯрдл-рдЬреИрд╕реЗ рдлрд╝рдВрдХреНрд╢рди

(pprof) list handleRequest
Total: 97803168
ROUTINE ======================== main.handleRequest in /home/arash/go/src/arvancloud/redins/redins.go
  2555943   83954299 (flat, cum) 85.84% of Total
        .          .     35: l          *handler.RateLimiter
        .          .     36: configFile string
        .          .     37:)
        .          .     38:
        .          .     39:func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
        .   11118401     40: context := handler.NewRequestContext(w, r)
  2555943    2555943     41: logger.Default.Debugf("handle request: [%d] %s %s", r.Id, context.RawName(), context.Type())
        .          .     42:
        .          .     43: if l.CanHandle(context.IP()) {
        .   70279955     44:  h.HandleRequest(context)
        .          .     45: } else {
        .          .     46:  context.Response(dns.RcodeRefused)
        .          .     47: }
        .          .     48:}
        .          .     49:

рд▓рд╛рдЗрди 41 рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬрдм рдбрд┐рдмрдЧрд┐рдВрдЧ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддрдм рднреА рдореЗрдореЛрд░реА рдХреЛ рд╡рд╣рд╛рдВ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рдо рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд╕реНрдХреЗрдк рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЧреЛ рдПрд╕реНрдХреЗрдк рдПрдирд╛рд▓рд┐рд╕рд┐рд╕ рдЯреВрд▓ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрдВрдкрд╛рдЗрд▓рд░ рдлреНрд▓реИрдЧ рд╣реИ

$ go build -gcflags '-m'

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдЖрдк рдПрдХ рдФрд░ рдореА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

$ go build -gcflags '-m '

рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП, рджреГрд╢реНрдп-рдПрдиреЛрдЯреЗрдЯ-рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред

$ go build -gcflags '-m'
.
.
.
../redins.go:39:20: leaking param: w
./redins.go:39:42: leaking param: r
./redins.go:41:55: r.MsgHdr.Id escapes to heap
./redins.go:41:75: context.RawName() escapes to heap
./redins.go:41:91: context.Request.Type() escapes to heap
./redins.go:41:23: handleRequest []interface {} literal does not escape
./redins.go:219:17: leaking param: path
.
.
.

рдпрд╣рд╛рдВ рд╕рднреА рдкреИрд░рд╛рдореАрдЯрд░ DebugfрдвреЗрд░ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдХрд╛рд░рдг рд╣реИ Debugf:

func (l *EventLogger) Debugf(format string, args ...interface{})

рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ argsрдХреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ interface{}рдЬреЛ рд╣рдореЗрд╢рд╛ рдвреЗрд░ рдкрд░ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдпрд╛ рддреЛ рдбреАрдмрдЧ рд▓реЙрдЧ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рд╢реВрдиреНрдп рд╡рд┐рддрд░рдг рдХреЗ рд╕рд╛рде рд▓реЙрдЧ рдХреЗ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд╝реАрд░реЛрд▓реЙрдЧ ред

рднрд╛рдЧрдиреЗ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, "рдЧреЛрд▓рдВрдЧ рдореЗрдВ рдЖрд╡рдВрдЯрди рдХрд╛ рдЖрд╡рдВрдЯрди" рджреЗрдЦреЗрдВ ред

рддрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ

(pprof) list reverseZone
Total: 100817064
ROUTINE ======================== arvancloud/redins/handler.reverseZone in /home/arash/go/src/arvancloud/redins/handler/handler.go
  6127746   10379086 (flat, cum) 10.29% of Total
        .          .    396:  logger.Default.Warning("log queue is full")
        .          .    397: }
        .          .    398:}
        .          .    399:
        .          .    400:func reverseZone(zone string) string {
        .    4251340    401: x := strings.Split(zone, ".")
        .          .    402: var y string
        .          .    403: for i := len(x) - 1; i >= 0; i-- {
  6127746    6127746    404:  y += x[i] + "."
        .          .    405: }
        .          .    406: return y
        .          .    407:}
        .          .    408:
        .          .    409:func (h *DnsRequestHandler) LoadZones() {
(pprof)

рдЪреВрдВрдХрд┐ рдЧреЛ рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИ, рдПрдХ рдЕрд╕реНрдерд╛рдпреА рд░реЗрдЦрд╛ рдмрдирд╛рдиреЗ рд╕реЗ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрди рд╣реЛрддрд╛ рд╣реИред Go 1.10 рд╕реЗ рд╢реБрд░реВ рдХрд░рдХреЗ, рдЖрдк рдЗрд╕реЗ strings.BuilderрдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред

(pprof) list reverseZone
Total: 93437002
ROUTINE ======================== arvancloud/redins/handler.reverseZone in /home/arash/go/src/arvancloud/redins/handler/handler.go
        0    7580611 (flat, cum)  8.11% of Total
        .          .    396:  logger.Default.Warning("log queue is full")
        .          .    397: }
        .          .    398:}
        .          .    399:
        .          .    400:func reverseZone(zone string) string {
        .    3681140    401: x := strings.Split(zone, ".")
        .          .    402: var sb strings.Builder
        .    3899471    403: sb.Grow(len(zone)+1)
        .          .    404: for i := len(x) - 1; i >= 0; i-- {
        .          .    405:  sb.WriteString(x[i])
        .          .    406:  sb.WriteByte('.')
        .          .    407: }
        .          .    408: return sb.String()

рдЪреВрдБрдХрд┐ рд╣рдо рдЙрд▓реНрдЯреЗ рд▓рд╛рдЗрди рдХреЗ рдореВрд▓реНрдп рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо Split()рдЗрд╕реЗ рдкреВрд░реА рд▓рд╛рдЗрди рдХреЛ рдлрд╝реНрд▓рд┐рдк рдХрд░рдХреЗ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред

(pprof) list reverseZone
Total: 89094296
ROUTINE ======================== arvancloud/redins/handler.reverseZone in /home/arash/go/src/arvancloud/redins/handler/handler.go
  3801168    3801168 (flat, cum)  4.27% of Total
        .          .    400:func reverseZone(zone string) []byte {
        .          .    401: runes := []rune("." + zone)
        .          .    402: for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        .          .    403:  runes[i], runes[j] = runes[j], runes[i]
        .          .    404: }
  3801168    3801168    405: return []byte(string(runes))
        .          .    406:}
        .          .    407:
        .          .    408:func (h *DnsRequestHandler) LoadZones() {
        .          .    409: h.LastZoneUpdate = time.Now()
        .          .    410: zones, err := h.Redis.SMembers("redins:zones")

рддрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЕрдзрд┐рдХ рдкрдврд╝реЗрдВ рдпрд╣рд╛рдБ ред

sync.Pool


(pprof) list GetASN
Total: 69005282
ROUTINE ======================== arvancloud/redins/handler.(*GeoIp).GetASN in /home/arash/go/src/arvancloud/redins/handler/geoip.go
  1146897    1146897 (flat, cum)  1.66% of Total
        .          .    231:func (g *GeoIp) GetASN(ip net.IP) (uint, error) {
  1146897    1146897    232: var record struct {
        .          .    233:  AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
        .          .    234: }
        .          .    235: err := g.ASNDB.Lookup(ip, &record)
        .          .    236: if err != nil {
        .          .    237:  logger.Default.Errorf("lookup failed : %s", err)
(pprof) list GetGeoLocation
Total: 69005282
ROUTINE ======================== arvancloud/redins/handler.(*GeoIp).GetGeoLocation in /home/arash/go/src/arvancloud/redins/handler/geoip.go
  1376298    3604572 (flat, cum)  5.22% of Total
        .          .    207:
        .          .    208:func (g *GeoIp) GetGeoLocation(ip net.IP) (latitude float64, longitude float64, country string, err error) {
        .          .    209: if !g.Enable || g.CountryDB == nil {
        .          .    210:  return
        .          .    211: }
  1376298    1376298    212: var record struct {
        .          .    213:  Location struct {
        .          .    214:   Latitude        float64 `maxminddb:"latitude"`
        .          .    215:   LongitudeOffset uintptr `maxminddb:"longitude"`
        .          .    216:  } `maxminddb:"location"`
        .          .    217:  Country struct {
        .          .    218:   ISOCode string `maxminddb:"iso_code"`
        .          .    219:  } `maxminddb:"country"`
        .          .    220: }
        .          .    221: // logger.Default.Debugf("ip : %s", ip)
        .          .    222: if err := g.CountryDB.Lookup(ip, &record); err != nil {
        .          .    223:  logger.Default.Errorf("lookup failed : %s", err)
        .          .    224:  return 0, 0, "", err
        .          .    225: }
        .    2228274    226: _ = g.CountryDB.Decode(record.Location.LongitudeOffset, &longitude)
        .          .    227: // logger.Default.Debug("lat = ", record.Location.Latitude, " lang = ", longitude, " country = ", record.Country.ISOCode)
        .          .    228: return record.Location.Latitude, longitude, record.Country.ISOCode, nil
        .          .    229:}
        .          .    230:
        .          .    231:func (g *GeoIp) GetASN(ip net.IP) (uint, error) {

рдЬрд┐рдпреЛрд▓реЛрдХреЗрд╢рди рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдореИрдХреНрд╕рдорд┐рдбрдм рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред рдЗрди рдХрд╛рд░реНрдпреЛрдВ interface{}рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рджреЗрдЦрд╛ рдерд╛, рдвреЗрд░ рд╢реВрдЯ рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддрд╛ рд╣реИред

рд╣рдо sync.Poolрдмрд╛рдж рдореЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЪрдпрдирд┐рдд рд▓реЗрдХрд┐рди рдЕрдкреНрд░рдпреБрдХреНрдд рддрддреНрд╡реЛрдВ рдХреЗ рдХреИрд╢рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред

type MMDBGeoLocation struct {
  Coordinations struct {
     Latitude        float64 `maxminddb:"latitude"`
     Longitude       float64
     LongitudeOffset uintptr `maxminddb:"longitude"`
  } `maxminddb:"location"`
  Country struct {
     ISOCode string `maxminddb:"iso_code"`
  } `maxminddb:"country"`
}

type MMDBASN struct {
  AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
}
func (g *GeoIp) GetGeoLocation(ip net.IP) (*MMDBGeoLocation, error) {
  if !g.Enable || g.CountryDB == nil {
     return nil, EMMDBNotAvailable
  }
  var record *MMDBGeoLocation = g.LocationPool.Get().(*MMDBGeoLocation)
  logger.Default.Debugf("ip : %s", ip)
  if err := g.CountryDB.Lookup(ip, &record); err != nil {
     logger.Default.Errorf("lookup failed : %s", err)
     return nil, err
  }
  _ = g.CountryDB.Decode(record.Coordinations.LongitudeOffset, &record.Coordinations.Longitude)
  logger.Default.Debug("lat = ", record.Coordinations.Latitude, " lang = ", record.Coordinations.Longitude, " country = ", record.Country.ISOCode)
  return record, nil
}

func (g *GeoIp) GetASN(ip net.IP) (uint, error) {
  var record *MMDBASN = g.AsnPool.Get().(*MMDBASN)
  err := g.ASNDB.Lookup(ip, record)
  if err != nil {
     logger.Default.Errorf("lookup failed : %s", err)
     return 0, err
  }
  logger.Default.Debug("asn = ", record.AutonomousSystemNumber)
  return record.AutonomousSystemNumber, nil
}

рдпрд╣рд╛рдВ рд╕рд┐рдВрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА ред

рдХрдИ рдЕрдиреНрдп рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдиреБрдХреВрд▓рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд▓рд╣рд╛рд▓, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рдХрд░ рдЪреБрдХреЗ рд╣реИрдВред рдореЗрдореЛрд░реА рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рддрдХрдиреАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрдЪреНрдЪ-рдкреНрд░рджрд░реНрд╢рди рдЧреЛ рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рдЖрд╡рдВрдЯрди рджрдХреНрд╖рддрд╛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ ред

рдкрд░рд┐рдгрд╛рдо


рдореЗрдореЛрд░реА рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо go tool trace"рдорд┐рдирд┐рдордо рдореНрдпреВрдЯреЗрдЯрд░ рдпреВрдЯрд┐рд▓рд╛рдЗрдЬреЗрд╢рди" рд╢реАрд░реНрд╖рдХ рдореЗрдВ рдПрдХ рдЖрд░реЗрдЦ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рдореНрдпреВрдЯреЗрдЯрд░ рдХрд╛ рдорддрд▓рдм рдЬреАрд╕реА рдирд╣реАрдВ рд╣реИред

рдЕрдиреБрдХреВрд▓рди рд╕реЗ рдкрд╣рд▓реЗ:



рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрд╢рд▓ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд┐рдирд╛ рд▓рдЧрднрдЧ 500 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреА рдПрдХ рдЦрд┐рдбрд╝рдХреА рд╣реИ (рдЬреАрд╕реА рд╕рднреА рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИ), рдФрд░ рд╣рдореЗрдВ рд▓рдВрдмреЗ рд╕рдордп рдореЗрдВ 80% рдкреНрд░рднрд╛рд╡реА рдЙрдкрдпреЛрдЧ рдХрднреА рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╢реВрдиреНрдп рдкреНрд░рднрд╛рд╡реА рдЙрдкрдпреЛрдЧ рдХреА рд╡рд┐рдВрдбреЛ рдпрдерд╛рд╕рдВрднрд╡ рдЫреЛрдЯреА рд╣реЛ, рдФрд░ 100% рдЙрдкрдпреЛрдЧ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ, рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ

рд╣реЛ:



рдирд┐рд╖реНрдХрд░реНрд╖


рдЧреЛ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдмреЗрд╣рддрд░ рдЙрдкрдпреЛрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗред

рдЖрдк рд╣рдорд╛рд░реЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ GitHub рдкрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ ред рдпрд╣рд╛рдБ рдПрдХ рдЧреИрд░-рдЕрдиреБрдХреВрд▓рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИ рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рдЕрдиреБрдХреВрд▓рд┐рдд рдПрдХ рд╣реИред

рдпрд╣ рдЙрдкрдпреЛрдЧреА рднреА рд╣реЛрдЧрд╛



рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдХреЛрд░реНрд╕ рдкрд░ рдорд┐рд▓рддреЗ рд╣реИрдВ !

Source: https://habr.com/ru/post/undefined/


All Articles