etcdctl 操作

用户操作

列出用户

$ etcdctl user list

添加用户

$ etcdctl user add devuser (input password)
Password of devuser:
Type password of devuser again for confirmation:
User devuser created

修改密码

$ etcdctl user passwd devuser

角色操作

添加role,名为 devteam

$ etcdctl role add devteam
Role devteam created

给用户 devuser 添加 role: devteam

$ etcdctl user grant-role devuser devteam
Role devteam is granted to user devuser

查看用户的信息

$ etcdctl user get devuser
User: devuser
Roles: devteam

赋予 role 相应的权限

$ etcdctl role grant-permission devteam --prefix=true readwrite
Role devteam updated

确保存在 root 用户,作为管理者

$ etcdctl user add root
Password of root:
Type password of root again for confirmation:
User root created

激活认证功能

$ etcdctl auth enable
Authentication Enabled

取消认证功能

$ etcdctl --user root:mypass auth disable
Authentication Disabled

重新激活认证功能

$ etcdctl auth enable
Authentication Enabled

查看已有的所有 role

$ etcdctl --user root:mypass role list
$ etcdctl --user root:mypassrole get devteam
Role devteam
KV Read:
KV Write:

取消dev的权限

$ etcdctl --user root:mypass role revoke-permission devteam --prefix=true

CMD/PowerShell中文乱码

乱码

Windows10 cmd中直接打印中文, 默认情况下会出现乱码.

解决方法

CMD

  1. 每次打开时输入 chcp 65001

  2. 修改注册表

    
    \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
    添加字符串值
    autorun
    chcp 65001

或者写一个 chcp65001.reg 文件, 导入值

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
"autorun"="chcp 65001"


### PowerShell

1. 使用管理员模式运行PowerShell

2. 创建一个 profile 文件

New-Item $PROFILE -ItemType File -Force


3. 在此文件在加入

文件默认在 C:\Users\[YourName]\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

4. 允许PowerShell启动时运行脚本

Set-ExecutionPolicy Unrestricted

Cocos Creator3d 中使用 protobuf

pb是个好同学

Cocos Creator 3d目前对 protobuf 支持还不是很好, 用传统集成到2d creator方式会遇到很多问题.
这里提供一种最简单(不一定是最好)的方式.

懒人直达 github

说明

protobufjs内建支持 load() 函数加载.proto文件, 稍微改造一下就可以用了.

集成步骤

1. 安装 protobufjs
npm install protobufjs
2. 复制 protobuf.js 到 cocos 项目中, 以插件方式导入
nodejs\node_modules\protobufjs\dist
3. 应用diff

改动diff

diff --git a/protobuf.js b/protobuf.js
index c3e1c02..2114e24 100644
--- a/protobuf.js
+++ b/protobuf.js
@@ -5279,6 +5279,12 @@ function SYNC() {} // eslint-disable-line no-empty-function
  * @returns {undefined}
  */
 Root.prototype.load = function load(filename, options, callback) {
+    var customPBSource = null;
+    if (typeof filename === "function") {
+        var obj = filename();
+        filename = obj.filename;
+        customPBSource = obj.content;
+    }
     if (typeof options === "function") {
         callback = options;
         options = undefined;
@@ -5371,22 +5377,28 @@ Root.prototype.load = function load(filename, options, callback) {
             }
             process(filename, source);
         } else {
-            ++queued;
-            util.fetch(filename, function(err, source) {
-                --queued;
-                /* istanbul ignore if */
-                if (!callback)
-                    return; // terminated meanwhile
-                if (err) {
-                    /* istanbul ignore else */
-                    if (!weak)
-                        finish(err);
-                    else if (!queued) // can't be covered reliably
-                        finish(null, self);
-                    return;
-                }
+            if (customPBSource != null) {
+                // console.log("I'm good boy", filename, customPBSource);
+                source = customPBSource;
                 process(filename, source);
-            });
+            } else {
+                ++queued;
+                util.fetch(filename, function(err, source) {
+                    --queued;
+                    /* istanbul ignore if */
+                    if (!callback)
+                        return; // terminated meanwhile
+                    if (err) {
+                        /* istanbul ignore else */
+                        if (!weak)
+                            finish(err);
+                        else if (!queued) // can't be covered reliably
+                            finish(null, self);
+                        return;
+                    }
+                    process(filename, source);
+                });
+            }
         }
     }
     var queued = 0;

使用方式

var content = `
        syntax = "proto2";
package game.proto;
message GameRequest {
  required string action  = 1;
  required string key     = 2;
  required string uuid    = 3;
  required int64  userId  = 4;
  optional bytes  data    = 5;
}
        `

        var PBReaderFunc = function() {
            return {
                filename: "game.proto",
                content:  content,
            }
        }

        protobuf.load(PBReaderFunc, function(err, root) {
            // console.error(err, root);
            if (err !== null) {
                console.error('加载错误', err);
                return;
            }
            var GameRequest = root.lookupType("game.proto.GameRequest");
            if(GameRequest === null) { // 解析失败了
                return;
            }
            var gameMessage = {
                action: "gameMatching",
                key:    "my-key",
                uuid:   "my-uuid",
                userId:  282,
            }
            // 编码
            var message    = GameRequest.create(gameMessage);
            var binaryData = GameRequest.encode(message).finish()
            console.log("编码二进制数据:", binaryData);
            // 解码
            var msg = GameRequest.decode(binaryData);
            var obj = GameRequest.toObject(msg);
            console.log("解码成对象", obj);
        })

Docker Management

Update restart policy

docker update --restart=always my-container
Flag Desc
no Do not automatically restart the container. (the default)
on-failure Restart the container if it exits due to an error, which manifests as a non-zero exit code.
always Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.

Golang Rate Limit流控

通常一个稳健的系统需要有一定的熔断或流控机制,用来防止突发或异常请求造成系统过高占用, 致使系统无法正常运作.
Go中无需使用第三方库,就可以很容易就可以做到流控.

QPS控制,10 QPS

通过Ticker触发消息,达到流控目的

import "time"

rate := time.Second / 10
throttle := time.Tick(rate)
for req := range requests {
  <-throttle  // rate limit our Service.Method RPCs
  go client.Call("Service.Method", req, ...)
}
import "time"

rate := time.Second / 10
burstLimit := 100
tick := time.NewTicker(rate)
defer tick.Stop()
throttle := make(chan time.Time, burstLimit)
go func() {
  for t := range tick.C {
    select {
      case throttle <- t:
      default:
    }
  }  // does not exit after tick.Stop()
}()
for req := range requests {
  <-throttle  // rate limit our Service.Method RPCs
  go client.Call("Service.Method", req, ...)
}