基于Nginx和Cookie的灰度系统

2023-11-27 22:11:45 381

import (
	"flag"
	"fmt"
	"net/http"
)

func main() {
	port := flag.Int("port", 4444, "HTTP server port")
	content := flag.String("content", "", "content")
	flag.Parse()

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		htmlContent := "<!DOCTYPE html><html><head><title>Test Page</title></head><body><h1>Hello, this is a " + *content + "!</h1></body></html>"
		w.Header().Set("Content-Type", "text/html")
		w.Write([]byte(htmlContent))
	})

	addr := fmt.Sprintf(":%d", *port)
	fmt.Printf("Server is running on http://localhost%s\n", addr)
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		fmt.Printf("Error starting server: %s\n", err)
	}
}

go build server.go

改改参数, 启动两个进程

nohup ./server -port 4445 -content test1 > /dev/null 2>&1 &

修改nginx配置

upstream go-server1 {
    server 127.0.0.1:4445;
}

upstream go-server2 {
    server 127.0.0.1:4446;
}

upstream default {
    server 127.0.0.1:4445;
}

server {
    listen       80;
    server_name  localhost;

    set $group "default";

    if ($http_cookie ~* "version=1.0") {
        set $group go-server1;
    }

    if ($http_cookie ~* "version=2.0") {
        set $group go-server2;
    }

    location / {
        proxy_pass http://$group;
    }
}

实现效果

root@localhost:/usr/local/nginx# curl -H "Cookie: version=1.0" localhost
<!DOCTYPE html><html><head><title>Test Page</title></head><body><h1>Hello, this is a test1!</h1></body></html>

root@localhost:/usr/local/nginx# curl -H "Cookie: version=2.0" localhost
<!DOCTYPE html><html><head><title>Test Page</title></head><body><h1>Hello, this is a test2!</h1></body></html>

这样,我们就实现了灰度的功能

配合灰度配置系统, 进行流量染色, 即可实现完整的灰度发布.

流量染色可以是后端代码处理, 也可以是独立的中间件处理

这里以代码处理示例

修改server.go代码如下

package main

import (
    "flag"
    "fmt"
    "math/rand"
    "net/http"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())

    port := flag.Int("port", 4444, "HTTP server port")
    content := flag.String("content", "", "content")
    flag.Parse()

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        htmlContent := "<!DOCTYPE html><html><head><title>Test Page</title></head><body><h1>Hello, this is a " + *content + "!</h1></body></html>"
        random := rand.Intn(10)
        if random < 2 {
            cookie := http.Cookie{
                Name:  "version",
                Value: "2.0",
            }
            http.SetCookie(w, &cookie)
        }
        w.Header().Set("Content-Type", "text/html")
        w.Write([]byte(htmlContent))
    })

    addr := fmt.Sprintf(":%d", *port)
    fmt.Printf("Server is running on http://localhost%s\n", addr)
    err := http.ListenAndServe(addr, nil)
    if err != nil {
        fmt.Printf("Error starting server: %s\n", err)
    }
}

在postman中发起调用, 请求几次后即可看到转发到了2.0

灰度系统=标记+染色

nginx proxy_buffer导致请求失败

chrome提示net::ERR_INCOMPLETE_CHUNKED_ENCODING一个接口部署在ecs上, postman访问可以, 前端项目访问失败请求成功的是没有经过nginx, 失败的是通过nginx转发 /api/xxxjava报错ClientAbortException: java.
2024-02-28

基于Nginx和Cookie的灰度系统

import ( "flag" "fmt" "net/http" ) func main() { port := flag.Int("port", 4444, "HTTP server port") content := flag.String("content", "", "conte
2023-11-27

Nginx相关命令

查看Nginx的版本号:nginx -V 启动Nginx:start nginx 或者 nginx 快速停止或关闭Nginx:nginx -s stop 正常停止或关闭Nginx:nginx -s quit 配置文件修改重装载命令:nginx -s reload 查看windows
2021-12-24

Nginx+Frp+Docker实现HTTPS内网穿透

内网穿透实用性非常强, 例如支付回调/访问内网数据库域名dns需要解析到服务器地址frp下载地址https://github.com/fatedier/frp/releases下载这两个文件frp_0.38.0_linux_amd64.tar.gzfrp_0.38.0_windows_amd64.z
2021-10-29

Nginx反向代理-传统单体项目相关配置

nginx.confserver { listen 80; server_name blog.22xcode.com; #路径重写, http转https rewrite ^(.*)$ https://$host$1 permanent; } blog.confse
2021-10-29

freemarker 时间显示不正常 设置时区

项目在本地开发的时候显示正常,部署上服务器就一直差8个小时,最后发现freemarker官方文档有这样的说明time_zone:时区的名称来显示并格式化时间。 默认情况下,使用JVM的时区。 也可以是 Java 时区 API 接受的值,或者 "JVM default" (从 FreeMarker 2
2020-03-28
IDEA 2019.1 xml 不高亮

IDEA 2019.1 xml 不高亮

前几天更新了idea后,发现xml里的代码都没有了高亮,变得跟记事本一个德性了打开setting ,搜索 File Types,找到xml项, 查看下方的匹配格式,果然没有xml,(idea真是厉害)点击右方的+,输入*.xml,点击ok,解决问题
2020-03-28

npm install 淘宝镜像

npm install --registry=https://registry.npm.taobao.org
2020-03-28
Java中方法的参数传递机制

Java中方法的参数传递机制

来看一段代码 public class Man { private String name; private Integer age; public String getName() { return name; } publi
2020-03-28
基于自定义注解手写权限控制

基于自定义注解手写权限控制

方法一: AOP 方法二: 拦截器项目结构项目依赖<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-w
2020-03-28

Docker 部署 详细全过程 附代码

Docker 部署本站 全过程环境:CentOS7.61. 安装Docker其他版本CentOS可以参考这个https://help.aliyun.com/document_detail/187598.html查看本机内核版本,内核版本需高于 3.10uname -r 确保 yum 包最新yum u
2020-03-28

SpringBoot 启动普通java工程

引入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.9</version> </dependency>
2020-03-28

Vue.js DOM操作

<template> <input type="button" @click="reply($event)" value="回复"> </template> export default { methods: { replyFun(e) {
2020-03-29
CentOS7编译调试OpenJDK12

CentOS7编译调试OpenJDK12

1. 下载源码https://hg.openjdk.java.net/jdk/jdk12点击左侧的browse,再点击zip,就可以下载zip格式的源码压缩包。unzip xxx.zip 解压文件2. 安装jdkyum install java-11-openjdk-devel -y3. 运行con
2020-04-23
编写自己的Spring Boot Starter

编写自己的Spring Boot Starter

1.新建一个maven项目命名规则统一是xxx-spring-boot-starter完整pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"
2020-06-29