当前位置:   article > 正文

docker-compose和traefik实现本机PXC集群的快速搭建和负载均衡_traefik 负载均衡权重

traefik 负载均衡权重

docker-compose和traefik实现本机PXC集群的快速搭建和负载均衡

什么是PXC?

Percona XtraDB Cluster (PXC) 是一个完全开源的 MySQL 数据库集群解决方案,它可确保高可用性,防止停机和数据丢失,并为不断增长的环境提供线性可扩展性。它将 Percona Server 和 Percona XtraBackup 与 Galera 库集成在一起,以实现同步多源复制。

PXC有哪些作用

  1. 同步复制:PXC使用Galera Cluster的同步复制技术,保证在所有节点之间的数据一致性。当一个节点接收到一个事务时,它提示事务复制到其他节点,从而实现数据的同步复制。
  2. 故障检测和自动故障转移:PXC具备故障检测和自动故障转移机制作。当一个节点宜机或不可用时,群会检测到并自动将请求路由到其他可用节点,以确保系统的可用性能。
  3. 读写负载均衡:由于PXC的多主复制架构众多,应用程序可以同时在节点上进行读和写操作,从而实现读写负载均值衡。
  4. 数据一致性和事务支持:PXC确保在整个维护集群中的所有节点之间的数据一致性,并提供完全支持ACID特性的事务处理。

PXC是一个强大的MySQL集群解决方案,可以提供高可用性、容错性和可扩展性。

PXC模式和Replication(传统主从)对比

image-20230623103027449

  1. 写操作延迟:PXC模式通常具有较低的写操作延迟,因为所有节点都可以处理写操作。而传统主从复制模式的写操作延迟较高,因为写操作必须由主节点处理并传播到从节点。
  2. 扩展性:PXC模式支持水平扩展,可以通过添加更多节点来增加集群的容量和性能。传统主从复制模式则需要在主节点上进行垂直扩展,增加其处理能力。
  3. 数据一致性:PXC模式通过多数派投票来实现数据一致性,并且在网络分区或节点故障时能够自动处理。传统主从复制模式在进行故障切换时可能会有一些数据丢失,需要手动处理数据一致性。
  4. 可用性:PXC模式在集群中的任何节点出现故障时都能保持可用性,因为所有节点都可以处理读写操作。传统主从复制模式在主节点故障时需要进行故障切换,可能会导致一段时间内的服务中断。

Traefik

image-20230623103137109

Traefik 是一种流行的开源反向代理和负载均衡器,广泛用于容器化环境。它提供了多种优势和功能,使其成为管理传入流量并将其路由到微服务或应用程序的热门选择。以下是常用Traefik的一些原因:

  1. 动态配置:Traefik 提供动态服务的配置和发现。它与 Docker、Kubernetes 和 Swarm 等容器编排器无缝集成,并且可以在部署或删除新服务时自动检测它们。这种动态配置消除了手动更新的需要,并使扩展和管理基础结构变得更加容易。
  2. 负载平衡:Traefik 提供内置的负载平衡功能。它将传入流量分布到应用程序或服务的多个实例之间,从而提高整体性能、可伸缩性和可靠性。Traefik 支持各种负载平衡算法,包括轮询、最少连接和 IP 哈希。
  3. **自动 SSL/TLS:**Traefik 简化了 SSL/TLS 证书的管理。它可以为您的服务自动获取和续订Let’s Encrypt SSL证书,确保客户端和服务器之间的安全通信,而无需手动证书管理。此功能可节省保护应用程序的时间和精力。
  4. 流量路由和中间件:Traefik 提供强大的流量路由功能,并支持基于主机、路径、标头等请求属性的各种路由规则。它还支持中间件,允许您向服务添加其他功能,如身份验证、速率限制、请求重写等。这种灵活性使您能够自定义和控制流量以满足您的特定要求。
  5. 监控和指标:Traefik 提供内置的监控和指标功能。它提供了一个基于 Web 的仪表板和一个 API,用于监视服务的运行状况和性能。此外,Traefik 可以与流行的监控系统(如 Prometheus、InfluxDB 和 Grafana)集成,使您能够收集和可视化有关基础架构的详细指标。
  6. 社区和生态系统:Traefik 拥有一个庞大而活跃的用户和贡献者社区。这是一个不断发展和改进的开源项目。社区提供支持、文档以及众多插件和扩展,以增强 Traefik 的功能并与其他工具集成。

快速开始

#拉取pxc镜像
docker pull percona/percona-xtradb-cluster:5.7.34-31.51
#此次指定版本,8.0后需要配置证书

  • 1
  • 2
  • 3
  • 4

新建docker-compose.yaml,这里我们选择traefik进行pxc集群的负载均衡,3306为统一的调用端口

version : '3.7'
networks:
  traefik-pxc:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.16.238.0/24
services:
  traefik:
    image: traefik:v2.4
    command:
      - "--providers.docker=true"
      - "--entrypoints.pxc.address=:3301"
      - "--api=true"  # 启用Traefik的API
      - "--api.insecure=true"# 启用Traefik的Web UI
      - "--providers.docker"
    ports:
      - "8080:8080"  # Traefik dashboard
      - "3301:3301"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      - traefik-pxc
  

  db1:
    container_name: db1
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.9
    ports:
      - "30001:3306"
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "MYSQL_ROOT_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
    volumes:
      - ./data/v1/data:/var/lib/mysql
      - ./data/v1/backup:/data
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"



  db2:
    container_name: db2
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.3
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30002:3306"
    volumes:
      - ./data/v2/data:/var/lib/mysql
      - ./data/v2/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db3:
    container_name: db3
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.4
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30003:3306"
    volumes:
      - ./data/v3/data:/var/lib/mysql
      - ./data/v3/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db4:
    container_name: db4
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.5
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30004:3306"
    volumes:
      - ./data/v4/data:/var/lib/mysql
      - ./data/v4/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  db5:
    container_name: db5
    image: percona/percona-xtradb-cluster:5.7.34-31.51
    privileged: true
    networks:
      traefik-pxc:
        ipv4_address: 172.16.238.6
    environment:
      - "CLUSTER_NAME=JWSPXC"
      - "XTRABACKUP_PASSWORD=db123456"
      - "TZ=Asia/Shanghai"
      - "CLUSTER_JOIN=db1"
    ports:
      - "30005:3306"
    volumes:
      - ./data/v5/data:/var/lib/mysql
      - ./data/v5/backup:/data
    depends_on:
      - db1
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.pxc-cluster.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.pxc-cluster.entrypoints=pxc"
      - "traefik.tcp.services.pxc-cluster.loadbalancer.server.port=3306"

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151

启动traefik

先启动traefik

docker-copmose up -d traefik
  • 1

启动pxc集群

再启动db1

docker-compose up -d db1
  • 1

注意:第一个节点启动比较慢,需要等待1分钟时间,可以使用数据据连接工具连接成功后再启动接下来的节点,这里你可以直接连映射的30001端口。

image-20230623100811168

然后我们再去traefik的UI界面8080端口,注意MySQL 连接通常使用 TCP/IP 进行通信,这里我们暴露的统一负载均衡端口为3301,有不了解traefik的同学,可以官方文档里面看一下,个人感觉还是很好上手的,要是只想了解docker的使用,可以看https://doc.traefik.io/traefik/routing/providers/docker/。

image-20230623101316591

image-20230623101519339

发现traefik已经负载成功,接着我们依次启动下面的节点

docker-compose up -d db2
docker-compose up -d db3
docker-compose up -d db4
docker-compose up -d db5
  • 1
  • 2
  • 3
  • 4

image-20230623101909878

五个节点负载均衡成功

image-20230623102233685

可以看到啊,我们在30001端口的节点创建gopan库,其他节点也同步了,接下来我们写个test再测试一下:

package test

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"testing"
)

func TestName(t *testing.T) {

	// 数据库连接参数
	dbHost := "localhost"
	dbPort := 3301
	dbUser := "root"
	dbPassword := "db123456"
	dbName := "gopan"

	// 构建连接字符串
	dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", dbUser, dbPassword, dbHost, dbPort, dbName)

	// 连接到数据库
	db, err := sql.Open("mysql", dataSourceName)
	if err != nil {
		fmt.Println("Failed to connect to database:", err)
		return
	}
	defer db.Close()

	// 测试连接
	err = db.Ping()
	if err != nil {
		fmt.Println("Failed to ping database:", err)
		return
	}

	fmt.Println("Connected to database successfully!")

	// 进行数据库操作...
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

image-20230623102414902

大功告成!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/721593
推荐阅读
相关标签