教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang 实现延迟消息原理与方法

golang 实现延迟消息原理与方法

发布时间:2022-02-11   编辑:jiaochengji.com
教程集为您提供golang 实现延迟消息原理与方法等资源,欢迎您收藏本站,我们将为您提供最新的golang 实现延迟消息原理与方法资源
<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>

原文:https://www.cnblogs.com/jkko123/p/7239420.html

实现延迟消息最主要的两个结构:

环形队列:通过golang中的数组实现,分成3600个slot。

任务集合:通过map[key]*Task,每个slot一个map,map的值就是我们要执行的任务。

原理图如下:

<pre><code class="lang-go hljs"><span class="token keyword">package</span> main <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"fmt"</span> <span class="token string">"errors"</span> <span class="token string">"time"</span> <span class="token punctuation">)</span> <span class="token keyword">type</span> DelayMessage <span class="token keyword">struct</span> <span class="token punctuation">{</span> curIndex <span class="token builtin">int</span><span class="token punctuation">;</span> slots <span class="token punctuation">[</span><span class="token number">3600</span><span class="token punctuation">]</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">*</span>Task<span class="token punctuation">;</span> closed <span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">;</span> taskClose <span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">;</span> timeClose <span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">;</span> startTime time<span class="token punctuation">.</span>Time<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">type</span> TaskFunc <span class="token keyword">func</span><span class="token punctuation">(</span>args <span class="token operator">...</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">type</span> Task <span class="token keyword">struct</span> <span class="token punctuation">{</span> cycleNum <span class="token builtin">int</span><span class="token punctuation">;</span> exec TaskFunc<span class="token punctuation">;</span> params <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</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 function">NewDelayMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>DelayMessage<span class="token punctuation">{</span> dm <span class="token operator">:=</span> <span class="token operator">&</span>DelayMessage<span class="token punctuation">{</span> curIndex<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> closed<span class="token punctuation">:</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span> taskClose<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span> timeClose<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span> startTime<span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Now</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">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> <span class="token number">3600</span><span class="token punctuation">;</span> i<span class="token operator"> </span><span class="token punctuation">{</span> dm<span class="token punctuation">.</span>slots<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token operator">*</span>Task<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> dm<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>dm <span class="token operator">*</span>DelayMessage<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> dm<span class="token punctuation">.</span>closed <span class="token operator"><-</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>dm <span class="token operator">*</span>DelayMessage<span class="token punctuation">)</span><span class="token function">taskLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"taskLoop exit"</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">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> dm<span class="token punctuation">.</span>taskClose<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token keyword">default</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> tasks <span class="token operator">:=</span> dm<span class="token punctuation">.</span>slots<span class="token punctuation">[</span>dm<span class="token punctuation">.</span>curIndex<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>tasks<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">{</span> <span class="token keyword">for</span> k<span class="token punctuation">,</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> tasks<span class="token punctuation">{</span> <span class="token keyword">if</span> v<span class="token punctuation">.</span>cycleNum <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">{</span> <span class="token keyword">go</span> v<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>v<span class="token punctuation">.</span>params<span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">delete</span><span class="token punctuation">(</span>tasks<span class="token punctuation">,</span> k<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span> v<span class="token punctuation">.</span>cycleNum<span class="token operator">--</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 punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//启动延迟消息</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>dm <span class="token operator">*</span>DelayMessage<span class="token punctuation">)</span> <span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">go</span> dm<span class="token punctuation">.</span><span class="token function">taskLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">go</span> dm<span class="token punctuation">.</span><span class="token function">timeLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</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>dm<span class="token punctuation">.</span>closed<span class="token punctuation">:</span> <span class="token punctuation">{</span> dm<span class="token punctuation">.</span>taskClose <span class="token operator"><-</span> <span class="token boolean">true</span><span class="token punctuation">;</span> dm<span class="token punctuation">.</span>timeClose <span class="token operator"><-</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">break</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">//处理每1秒移动下标</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>dm <span class="token operator">*</span>DelayMessage<span class="token punctuation">)</span> <span class="token function">timeLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"timeLoop exit"</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> tick <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><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>dm<span class="token punctuation">.</span>timeClose<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 keyword">case</span> <span class="token operator"><-</span>tick<span class="token punctuation">.</span>C<span class="token punctuation">:</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"2006-01-02 15:04:05"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//判断当前下标,如果等于3599则重置为0,否则加1</span> <span class="token keyword">if</span> dm<span class="token punctuation">.</span>curIndex <span class="token operator">==</span> <span class="token number">3599</span> <span class="token punctuation">{</span> dm<span class="token punctuation">.</span>curIndex <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> dm<span class="token punctuation">.</span>curIndex<span class="token operator"> </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> <span class="token keyword">func</span> <span class="token punctuation">(</span>dm <span class="token operator">*</span>DelayMessage<span class="token punctuation">)</span> <span class="token function">AddTask</span><span class="token punctuation">(</span>t time<span class="token punctuation">.</span>Time<span class="token punctuation">,</span> key <span class="token builtin">string</span><span class="token punctuation">,</span> exec TaskFunc<span class="token punctuation">,</span> params <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> dm<span class="token punctuation">.</span>startTime<span class="token punctuation">.</span><span class="token function">After</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> errors<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">"时间错误"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//当前时间与指定时间相差秒数</span> subSecond <span class="token operator">:=</span> t<span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> dm<span class="token punctuation">.</span>startTime<span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//计算循环次数</span> cycleNum <span class="token operator">:=</span> <span class="token function">int</span><span class="token punctuation">(</span>subSecond <span class="token operator">/</span> <span class="token number">3600</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//计算任务所在的slots的下标</span> ix <span class="token operator">:=</span> subSecond <span class="token operator">%</span> <span class="token number">3600</span><span class="token punctuation">;</span> <span class="token comment">//把任务加入tasks中</span> tasks <span class="token operator">:=</span> dm<span class="token punctuation">.</span>slots<span class="token punctuation">[</span>ix<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token boolean">_</span><span class="token punctuation">,</span> ok <span class="token operator">:=</span> tasks<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span> <span class="token keyword">return</span> errors<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">"该slots中已存在key为"</span> <span class="token operator"> </span> key <span class="token operator"> </span> <span class="token string">"的任务"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> tasks<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&</span>Task<span class="token punctuation">{</span> cycleNum<span class="token punctuation">:</span> cycleNum<span class="token punctuation">,</span> exec<span class="token punctuation">:</span> exec<span class="token punctuation">,</span> params<span class="token punctuation">:</span> params<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">nil</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//创建延迟消息</span> dm <span class="token operator">:=</span> <span class="token function">NewDelayMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//添加任务</span> dm<span class="token punctuation">.</span><span class="token function">AddTask</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"test1"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>args <span class="token operator">...</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>args<span class="token operator">...</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 keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> dm<span class="token punctuation">.</span><span class="token function">AddTask</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"test2"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>args <span class="token operator">...</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>args<span class="token operator">...</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 keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> dm<span class="token punctuation">.</span><span class="token function">AddTask</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"test3"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>args <span class="token operator">...</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>args<span class="token operator">...</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 keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"world"</span><span class="token punctuation">,</span> <span class="token string">"test"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> dm<span class="token punctuation">.</span><span class="token function">AddTask</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"test4"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>args <span class="token operator">...</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> arg <span class="token operator">:=</span> <span class="token keyword">range</span> args <span class="token punctuation">{</span> sum <span class="token operator"> =</span> arg<span class="token punctuation">;</span> <span class="token punctuation">}</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"sum : "</span><span class="token punctuation">,</span> sum<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 keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//40秒后关闭</span> time<span class="token punctuation">.</span><span class="token function">AfterFunc</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">40</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> dm<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 punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> dm<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> 到此这篇关于“golang 实现延迟消息原理与方法”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
订阅redis接收的json字符串斜杠_用 Golang 实现基于 Redis 的安全高效 RPC 通信
go 关键字之 defer
go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
图解 Go 中的延迟调用 defer
如何在生产环境mysql删除亿万级数据解并且不影响数据库主从延迟的解决方案
Go语言的实时GC——理论与实践
订单系统设计 —— 数据同步与监控
Golang defer 你不知道的事
Go:defer 语句如何工作
使用 Go 重构 - Goroutine 并发

[关闭]
~ ~