{"id":225982,"date":"2020-12-14T20:20:26","date_gmt":"2020-12-14T12:20:26","guid":{"rendered":"http:\/\/4563.org\/?p=225982"},"modified":"2020-12-14T20:20:26","modified_gmt":"2020-12-14T12:20:26","slug":"uber-go-ratelimit-%e8%8f%9c%e9%b8%a1%e6%b1%82%e5%8a%a9","status":"publish","type":"post","link":"http:\/\/4563.org\/?p=225982","title":{"rendered":"uber-go\/ratelimit \u83dc\u9e21\u6c42\u52a9"},"content":{"rendered":"<div>\n<div>\n<div>\n<h1>                  uber-go\/ratelimit \u83dc\u9e21\u6c42\u52a9               <\/h1>\n<p> <\/p>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : bigHave <\/span>  <span><i><\/i> 6<\/span> <\/div>\n<div> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div isfirst=\"1\"> <\/p>\n<p>uber \u5f00\u6e90\u7684\u9650\u6d41\u7b97\u6cd5\uff0c\u4ee3\u7801\u4e0d\u591a\uff0c\u5c1d\u8bd5\u7406\u89e3\u4f46\u662f\u6ca1\u600e\u4e48\u7406\u89e3\u3002\u6709\u6ca1\u6709\u5927\u4f6c\u6307\u70b9\u4e00\u4e8c.\u4e3b\u8981\u4e0d\u7406\u89e3\u7684\u70b9\u5728\u4e8e\u8fd9\u4e2a for \u5faa\u73af<\/p>\n<pre><code>\/\/ Take blocks to ensure that the time spent between multiple \/\/ Take calls is on average time.Second\/rate. func (t *limiter) Take() time.Time {  newState := state{}  taken := false  for !taken {   now := t.clock.Now()    previousStatePointer := atomic.LoadPointer(&amp;t.state)   oldState := (*state)(previousStatePointer)    newState = state{}   newState.last = now    \/\/ If this is our first request, then we allow it.   if oldState.last.IsZero() {    taken = atomic.CompareAndSwapPointer(&amp;t.state, previousStatePointer, unsafe.Pointer(&amp;newState))    continue   }    \/\/ sleepFor calculates how much time we should sleep based on   \/\/ the perRequest budget and how long the last request took.   \/\/ Since the request may take longer than the budget, this number   \/\/ can get negative, and is summed across requests.   newState.sleepFor += t.perRequest - now.Sub(oldState.last)   \/\/ We shouldn't allow sleepFor to get too negative, since it would mean that   \/\/ a service that slowed down a lot for a short period of time would get   \/\/ a much higher RPS following that.   if newState.sleepFor &lt; t.maxSlack {    newState.sleepFor = t.maxSlack   }   if newState.sleepFor &gt; 0 {    newState.last = newState.last.Add(newState.sleepFor)   }   taken = atomic.CompareAndSwapPointer(&amp;t.state, previousStatePointer, unsafe.Pointer(&amp;newState))  }  t.clock.Sleep(newState.sleepFor)  return newState.last } <\/code><\/pre>\n<\/p><\/div>\n<div> <b>\u5927\u4f6c\u6709\u8a71\u8aaa<\/b> (<span>2<\/span>)        <\/div>\n<div> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<ul>\n<li data-pid=\"4506569\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : CRVV <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             var counter int64<\/p>\n<p>\u7136\u540e\u5982\u679c\u6709\u591a\u4e2a\u7ebf\u7a0b\u6267\u884c\u4e0b\u9762\u8fd9\u4e2a\u5faa\u73af\uff0c\u6bcf\u6b21 break \u90fd\u4f1a\u7ed9 counter \u52a0\u4e00<br \/>for {<br \/>counter0 := atomic.LoadInt64(&amp;counter)<br \/>if atomic.CompareAndSwap(&amp;counter, counter0, counter+1) {<br \/>break<br \/>}<br \/>}<\/p>\n<p>\u8fd9\u79cd\u5c31\u662f\u6240\u8c13\u7684 lock-free\uff0c\u628a\u5b83\u5199\u6210\u7528 lock \u7684\u5f62\u5f0f\uff0c\u518d\u628a\u90a3\u51e0\u4e2a if \u53bb\u6389\uff0c\u8fd9\u4e2a\u51fd\u6570\u5176\u5b9e\u5c31\u662f<\/p>\n<p>func (t *limiter) Take() time.Time {<\/p>\n<p>mutex.Lock()<\/p>\n<p>oldState := t.state<br \/>newState = state{}<br \/>now := t.clock.Now()<br \/>newState.last = now<br \/>newState.sleepFor += t.perRequest &#8211; now.Sub(oldState.last)<\/p>\n<p>t.state = &amp;newState<br \/>mutex.Unlock()<\/p>\n<p>t.clock.Sleep(newState.sleepFor)<br \/>return newState.last<br \/>}<\/p>\n<p>\u7136\u540e\u5e94\u8be5\u5f88\u597d\u61c2\u4e86                                                            <\/p><\/div>\n<\/p><\/div>\n<\/li>\n<li data-pid=\"4506570\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u4e3b<\/span> <span>\u8cc7\u6df1\u5927\u4f6c : bigHave <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             @CRVV \u611f\u8c22\u3002\u7b2c\u4e00\u6b21\u5728 V2EX \u53d1\u5e16\u5c31\u5f97\u5230\u4e86\u9ad8\u6548\u5e2e\u52a9\uff0c\u592a\u68d2\u4e86                                                            <\/div>\n<\/p><\/div>\n<\/li>\n<li>\n","protected":false},"excerpt":{"rendered":"<p>uber-go\/ratelimit&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/225982"}],"collection":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=225982"}],"version-history":[{"count":0,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/225982\/revisions"}],"wp:attachment":[{"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=225982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=225982"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=225982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}