教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang channel实现limiter

Golang channel实现limiter

发布时间:2022-02-27   编辑:jiaochengji.com
教程集为您提供Golang channel实现limiter等资源,欢迎您收藏本站,我们将为您提供最新的Golang channel实现limiter资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h3>普通Limiter</h3>

特点:无时间限制,只要不超过数量就可通过

<pre><code class="lang-go hljs"><span class="token comment">// 基于channel阻塞实现</span> <span class="token comment">// 缺点:阻塞无时间限制</span> <span class="token keyword">type</span> <span class="token punctuation">(</span> ChannelLimiter <span class="token keyword">struct</span> <span class="token punctuation">{</span> bufferChannel <span class="token keyword">chan</span> golang<span class="token punctuation">.</span>PlaceholderType <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">NewChannelLimiter</span><span class="token punctuation">(</span>limit <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token operator">*</span>ChannelLimiter <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator">&</span>ChannelLimiter<span class="token punctuation">{</span>bufferChannel<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> golang<span class="token punctuation">.</span>PlaceholderType<span class="token punctuation">,</span> limit<span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>ChannelLimiter<span class="token punctuation">)</span> <span class="token function">Allow</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span> <span class="token keyword">select</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> l<span class="token punctuation">.</span>bufferChannel <span class="token operator"><-</span> golang<span class="token punctuation">.</span>Placeholder<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>ChannelLimiter<span class="token punctuation">)</span> <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span> <span class="token operator"><-</span>l<span class="token punctuation">.</span>bufferChannel <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>l <span class="token operator">*</span>ChannelLimiter<span class="token punctuation">)</span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">close</span><span class="token punctuation">(</span>l<span class="token punctuation">.</span>bufferChannel<span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h3>
令牌桶Limiter</h3>

特点:令牌桶

<pre><code class="lang-go hljs"><span class="token comment">// 令牌桶算法</span> <span class="token comment">// 产生令牌:均为间隔时间内(1秒)向指定桶中产生指定数量的令牌</span> <span class="token comment">// 消费令牌:从桶中获取令牌并消费</span> <span class="token comment">// 思路:通过channel阻塞原理来实现</span> <span class="token keyword">type</span> <span class="token punctuation">(</span> TokenBucketLimiter <span class="token keyword">struct</span> <span class="token punctuation">{</span> t <span class="token operator">*</span>time<span class="token punctuation">.</span>Ticker bucket <span class="token keyword">chan</span> golang<span class="token punctuation">.</span>PlaceholderType doneC channel<span class="token punctuation">.</span>DoneChan limit <span class="token builtin">int</span> rate <span class="token builtin">int</span> stop <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token comment">// rate:token put rates per second</span> <span class="token comment">// limit:max limit</span> <span class="token keyword">func</span> <span class="token function">NewTokenBucketLimiter</span><span class="token punctuation">(</span>rate<span class="token punctuation">,</span> limit <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token operator">*</span>TokenBucketLimiter <span class="token punctuation">{</span> t <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">NewTicker</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span> doneC <span class="token operator">:=</span> channel<span class="token punctuation">.</span><span class="token function">NewDoneChan</span><span class="token punctuation">(</span><span class="token punctuation">)</span> bucket <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> golang<span class="token punctuation">.</span>PlaceholderType<span class="token punctuation">,</span> limit<span class="token punctuation">)</span> tbl <span class="token operator">:=</span> <span class="token operator">&</span>TokenBucketLimiter<span class="token punctuation">{</span> rate<span class="token punctuation">:</span> rate<span class="token punctuation">,</span> t<span class="token punctuation">:</span> t<span class="token punctuation">,</span> bucket<span class="token punctuation">:</span> bucket<span class="token punctuation">,</span> doneC<span class="token punctuation">:</span> doneC<span class="token punctuation">,</span> limit<span class="token punctuation">:</span> limit<span class="token punctuation">,</span> <span class="token comment">// only stop once</span> stop<span class="token punctuation">:</span> routine<span class="token punctuation">.</span><span class="token function">DoOnce</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> doneC<span class="token punctuation">.</span><span class="token function">Stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token function">close</span><span class="token punctuation">(</span>bucket<span class="token punctuation">)</span> t<span class="token punctuation">.</span><span class="token function">Stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token comment">// 定时放置令牌</span> tbl<span class="token punctuation">.</span><span class="token function">asyncPutTokens</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">return</span> tbl <span class="token punctuation">}</span> <span class="token comment">// 通过尝试put golang.Placeholder 来达到是否有令牌可消费</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>tbl <span class="token operator">*</span>TokenBucketLimiter<span class="token punctuation">)</span> <span class="token function">Allow</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span> <span class="token keyword">select</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> tbl<span class="token punctuation">.</span>bucket <span class="token operator"><-</span> golang<span class="token punctuation">.</span>Placeholder<span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token keyword">case</span> <span class="token operator"><-</span>tbl<span class="token punctuation">.</span>doneC<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>tbl <span class="token operator">*</span>TokenBucketLimiter<span class="token punctuation">)</span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> tbl<span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// 通过排空channel达到放置token的目的</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>tbl <span class="token operator">*</span>TokenBucketLimiter<span class="token punctuation">)</span> <span class="token function">asyncPutTokens</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> safe<span class="token punctuation">.</span><span class="token function">GoRun</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">{</span> <span class="token keyword">select</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token operator"><-</span>tbl<span class="token punctuation">.</span>t<span class="token punctuation">.</span>C<span class="token punctuation">:</span> tbl<span class="token punctuation">.</span><span class="token function">drain</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">case</span> <span class="token operator"><-</span>tbl<span class="token punctuation">.</span>doneC<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>tbl <span class="token operator">*</span>TokenBucketLimiter<span class="token punctuation">)</span> <span class="token function">drain</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> tbl<span class="token punctuation">.</span>limit<span class="token punctuation">;</span> i<span class="token operator"> </span> <span class="token punctuation">{</span> <span class="token keyword">select</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token operator"><-</span>tbl<span class="token punctuation">.</span>bucket<span class="token punctuation">:</span> <span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> 到此这篇关于“Golang channel实现limiter”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:

[关闭]
~ ~