Use Azure Devops Pipeline to build && deploy your project

this post will teach you how to deploy your own Docker registry and how to use Microsoft Azure Devops to automatically building your Github Go project, and deploy to your Docker Swarm Server

How it works

Use Azure Devops Pipeline to build && deploy your project - 1

  1. Pipeline download your github project
  2. Build your code by Dockerfile, make docker image then push to your own Docker registry
  3. Execute Bash command in Pipeline, pull off latest image of your project then update Docker swarm service

Continue reading Use Azure Devops Pipeline to build && deploy your project

Write a Microservice via Go-Micro

I’ve learning Go-Micro around a month, that I wanna write an article to record what I have learnt. In case I forgot it, I can still pick it up by reading this article. What I have wrote about might be inaccurate, I’m very glad that you can correct it.

Architecture

Write a Microservice via Go-Micro - 1

my design about Microservices architecture

Continue reading Write a Microservice via Go-Micro

websocket nginx reverse proxy configuration

location /test {
        proxy_pass http://127.0.0.1:8080/ws; # target address

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_http_version 1.1;
        # websocket headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 30;
}

Echo frameworks context bind twice without losing data

Retrieve data from echo middleware, may cause you get code=400, message=EOF error.

Context.Bind only can bind once, after the request passed the middleware,the request data reader is running out, Context.Bind() function read request body data from the socket buffer, once you took it out, it just gone

that’s why it returns EOF error.

solution

func main() {
    echoServer := echo.New()
    echoServer.POST("/api", webfunc1, middleware1)
    echoServer.Start(":8080")
}

func middleware1(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        // read origin body bytes
        var bodyBytes []byte
        if c.Request().Body != nil {
            bodyBytes, _ = ioutil.ReadAll(c.Request().Body)
            // write back to request body
            c.Request().Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
            // parse json data
            reqData := struct {
                ID string `json:"id"`
            }{}
            err := json.Unmarshal(bodyBytes, &reqData)
            if err != nil {
                return c.JSON(400, "error json.")
            }
            fmt.Println(reqData.ID)
        }
        return next(c)
    }
}

func webfunc1(c echo.Context) error {
    reqData := struct {
        Data string `json:"data"`
    }{}
    c.Bind(&reqData)
    fmt.Println(reqData.Data)
    return c.HTML(200, "200 OK.")
}

Golang: Read from an io.ReadWriter without losing its content

Python 异步任务模块 Celery 快速上手 (一)

基本使用

第一步,建立一个celery类的对象,传入一个名称(后续需要这个名称来执行异步任务), 配置消息代理,这里配置了本地redis服务器的第0个数据库

    """
    tasks.py
    """
    from celery import Celery
    celery_app = Celery('name', broker='redis://localhost:6379/0')

那这样就可以通过task装饰器来建立一个简单的异步任务了

    """
    tasks.py
    """
    import time

    @celery_app.task
    def task_name(someone):
        time.sleep(5)
        print('hello {}'.format(someone))

建立好异步任务之后,可以在外部调用这个任务

    from tasks import task_name
    # 任务用过delay方法可以传入参数,方法执行后并不会阻塞后续代码
    task_name.delay('task')
    print('start running!')
    # 也可以不立即执行,可以先用s方法传入参数
    task_name.s('task')
    print('start running!')
    task_name.delay()

对了执行celery命令celery -A name worker, 执行后注册的任务会在console里面输出

数据持久化

想要delay的函数返回的结果就需要在建立celery对象中加入一个backend参数

    """
    tasks.py
    """
    from celery import Celery
    celery_app = Celery('name', broker='redis://localhost:6379/0', backend='redis://localhost:6379/1')

建立一个任务带返回数据功能的

    """
    tasks.py
    """
    import time

    @celery_app.task
    def say_hello(to):
        time.sleep(5)
        return "Hello {}".format(to)

通过ready()方法可以获取任务是否完成,而get()可以获取任务返回结果

    from tasks import say_hello
    import time

    t = say_hello('hello')
    while True:
        r = t.ready()
        if not r:
            print("task done? {}".format(r))
            continue
        print('task done: {}'.format(t.get()))
        break

下一篇详细讲讲Celery的Task类