如何用 HAproxy 实施高可用部署 | OceanBase 实践

news2024/9/19 16:53:00

背景介绍

最近,我们部署了Oceanbase数据库(以下简称OB),并将部分业务迁移至OB中运行。在部署过程中,我们虽然配置了3个OBProxy,但没有为它们设置高可用配置,应用被固定到某一个OBProxy 上,这使我们在实际的运维工作中遇到了诸多不便。例如,当需要对OB集群中的某个主机进行维护时,我们必须提前与业务部门沟通,协商停机时间,并要求业务方配合关停服务,这样的流程不仅繁琐,而且给业务方带来了不佳的体验。

由于在网上没有看到如何利用开源组件,实现OBProxy的高可用的内容,以提高OB集群对于故障、停机等服务不可用情况的容忍度,所以,我们尝试用HAproxy作为HA组件来反代OBProxy,并将其记录与分享给大家参考。如有更好的建议,欢迎随时留言沟通。

拓扑介绍

未命名文件.png

准备工作

主机配置:

系统:https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso内核:3.10.0-1160.el7.x86_64

$ grubby --update-kernel=ALL --args="numa=off"
$ grubby --update-kernel=ALL --args="transparent_hugepage=never"

$ systemctl stop postfix.service
$ systemctl disable postfix 
$ systemctl disable auditd
$ systemctl disable kdump

$ systemctl stop firewalld.service
$ systemctl disable firewalld.service
$ sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config
$ setenforce 0

$ sed -i "s/\#UseDNS yes/UseDNS no/g" /etc/ssh/sshd_config
$ sed -i "s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g" /etc/ssh/sshd_config

YUM源准备:

# 备份
$ mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
$ mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
$ mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup

# 下载Base源
$ curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
$ sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
# 下载epel源
$ curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
$ yum clean all
$ yum makecache

内核参数

$ cat >> /etc/sysctl.conf << EOF
# for oceanbase
## 修改内核异步 I/O 限制
fs.aio-max-nr=1048576

## 网络优化
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 10000 
net.core.rmem_default = 16777216 
net.core.wmem_default = 16777216 
net.core.rmem_max = 16777216 
net.core.wmem_max = 16777216

net.ipv4.ip_local_port_range = 3500 65535 
net.ipv4.ip_forward = 0 
net.ipv4.conf.default.rp_filter = 1 
net.ipv4.conf.default.accept_source_route = 0 
net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216 
net.ipv4.tcp_max_syn_backlog = 16384 
net.ipv4.tcp_fin_timeout = 15 
net.ipv4.tcp_max_syn_backlog = 16384 
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_tw_recycle = 1 
net.ipv4.tcp_slow_start_after_idle=0

vm.swappiness = 0
vm.min_free_kbytes = 2097152
fs.file-max = 6573688

# 修改进程可以拥有的虚拟内存区域数量
vm.max_map_count = 655360

# 此处为 OceanBase 数据库的 data 目录
kernel.core_pattern = /data/core-%e-%p-%t
EOF
$ sysctl -p
$ cat >>/etc/security/limits.conf <<EOF
* soft nproc 655300
* hard nproc 655300
* soft nofile 655300
* hard nofile 655300
* soft core unlimited
* hard core unlimited
* soft stack unlimited
* hard stack unlimited
admin soft nofile 655350
admin hard nofile 655350
admin soft stack unlimited
admin hard stack unlimited
admin soft nproc 655360
admin hard nproc 655360
EOF

$ cat >>/etc/security/limits.d/20-nproc.conf <<EOF
*          soft    nproc     655300
*          soft    nofile    655300
*          soft    core      unlimited
*          soft    stack     unlimited
root       soft    nproc     unlimited
EOF

基础软件包安装

$ yum install -y tree nmap dos2unix lrzsz nv lsof wget tcpdump htop iftop iotop sysstat nethogs
$ yum install -y psmisc net-tools bash-completion vim-enhanced
# 安装bash命令tab自动补全组件
$    
# 安装vim编辑器
$ yum -y install vim screen lrzsz tree psmisc
# 安装压缩解压工具
$ yum -y install zip unzip bzip2 gdisk
# 安装网络及性能监控工具
$ yum -y install telnet net-tools sysstat iftop lsof iotop htop dstat
到这一步,最好重启一下机器。

安装HAproxy

安装HAproxy

两台机器都采用相同的操作

$ yum install -y haproxy

验证软件包是否被正确安装

$ rpm -qa | grep haproxy
haproxy-1.5.18-9.el7_9.1.x86_64
版本可能与本文存在差异,但一定要高于1.4.9

准备一个数据目录,如果有条件,可以把数据目录单独mount到一个磁盘上面

$ mkdir -p /data/haproxy
$ chown -R haproxy:haproxy /data/haproxy

准备HAproxy的配置文件

备份原始的配置文件(两个节点都需要操作)

mv /etc/haproxy/haproxy.cfg{,.bak}

节点OBHA-T1的配置文件(/etc/haproxy/haproxy.cfg):

## https://cloud.tencent.com/developer/article/2046159
# 全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关
global
  # 定义全局的syslog服务器,接收haproxy启动和停止的日志。最多可以定义两个;
  # log  <address> <facility> [max level [min level]] 
  log  127.0.0.1 local0 err
  # 设定每haproxy进程所接受的最大并发连接数,当达到此限定连接数后将不再接受新的连接。该参数特指和客户端的连接数,不包括和服务端的连接。等同于命令行选项"-n";"ulimit -n"就是根据此值进行自动调整的;
  maxconn  8000
  # 设定每进程能够打开的最大文件描述符数量,默认haproxy会自动进行计算,因此不推荐修改此选项;(不建议设置项)
  #ulimit-n  16384
  # 和多进程haproxy有关,由于不建议使用多进程,所以也不建议设置此项。但建议设置为"stats socket"将套接字和本地文件进行绑定,如"stats socket /var/lib/haproxy/stats"。
  #stats timeout 30s
  # 修改haproxy工作目录至指定目录,可提升haproxy安全级别,但要确保必须为空且任何用户均不能有写权限;
  chroot /data/haproxy
  # 以指定的UID或用户名身份运行haproxy进程;
  user haproxy
  # 以指定的GID或组名运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
  group haproxy
  # 让haproxy以守护进程的方式工作于后台,等同于命令行的"-D"选项,当然,也可以在命令行中以"-db"选项将其禁用;(建议设置项)
  daemon

# (配置默认参数,这些参数可以被用到frontend,backend,Listen组件)
# 在此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中,
# 因引,某些参数属于公用的配置,只需要在defaults部分添加一次即可。
# 而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,Defaults部分参数对应的值自动被覆盖。
defaults
  # 所处理的类别(7层代理http,4层代理tcp) 
  mode  tcp
  # 最大连接数
  maxconn 6000
  log global
  # 日志类别为http日志格式 
  option  httplog
  # 不记录健康检查日志信息 
  option dontlognull
  # 3次连接失败就认为服务器不可用,也可以通过后面设置 
  retries 3
  # 设置连接超时时间
  timeout connect 10s
  # 设置连接超时时间
  timeout client  1m
  # 设置服务器超时时间 
  timeout server  1m
  # 默认队列超时时间
  timeout queue 1m
  # 设置心跳检查超时时间
  timeout check 10s
  # 默认持久连接超时时间
  # timeout http-keep-alive 15s
  # 默认http请求超时时间
  # timeout http-request 10s


# ( 接收请求的前端虚拟节点,Frontend可以更加规则直接指定具体使用后端的backend)
# frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。
# 通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。
# forntend可以根据ACL规则直接指定要使用的后端backend。
frontend obrsproxy
  bind 0.0.0.0:2883
  bind 127.0.0.1:2883
  mode tcp
  option tcplog
  default_backend obrsproxy

# (后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器)
# 在HAProxy1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。
# 为了保持兼容性,haproxy新的版本依然保留了listen组件配置试。两种配置方式任选一中。
backend obrsproxy
  mode tcp
  option tcplog
  option tcp-check
  balance roundrobin
  default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
  server OBC-T1    192.168.1.36:2883  check
  server OBC-T2    192.168.1.37:2883  check
  server OBC-T3    192.168.1.38:2883  check

#  (Fronted和backend的组合体) 比如haproxy实例状态监控部分配置
# 定义一个监控页面,监听在18080端口,并启用了验证机制
Listen stats
  # 设置模式为http
  mode http
  # haroxy的ip地址和端口
  bind 192.168.1.33:18080 
  # 错误日志记录
  log 127.0.0.1 local3 err
  # 设置监控页面刷新时间:30s 
  stats refresh 30s
  stats enable
  # 隐藏统计页面的HAproxy版本信息 
  stats hide-version
   # 设置监控页面的url
  stats uri /haproxyadmin?stats #开启网页访问
  # 设置页面提示信息 
  stats realm Haproxy\ Statistics
   # 用户名和密码
  stats auth admin:admin
  # 设置手工启动/禁用,后端服务器(haproxy-1.4.9以后版本)
  stats admin if TRUE

节点OBHA-T2的配置文件(/etc/haproxy/haproxy.cfg):

global
  log  127.0.0.1 local0 err
  maxconn  8000
  chroot /data/haproxy
  user haproxy
  group haproxy
  daemon

defaults
  mode  tcp
  maxconn 6000
  log global
  option  httplog
  option dontlognull
  retries 3
  timeout connect 10s
  timeout client  1m 
  timeout server  1m
  timeout queue 1m
  timeout check 10s

frontend obrsproxy
  bind 0.0.0.0:2883
  bind 127.0.0.1:2883
  mode tcp
  option tcplog
  default_backend obrsproxy

backend obrsproxy
  mode tcp
  option tcplog
  option tcp-check
  balance roundrobin
  default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
  server OBC-T1    192.168.1.36:2883  check
  server OBC-T2    192.168.1.37:2883  check
  server OBC-T3    192.168.1.38:2883  check

Listen stats
  mode http
  bind 192.168.1.34:18080 
  log 127.0.0.1 local3 err
  stats refresh 30s
  stats enable
  stats hide-version
  stats uri /haproxyadmin?stats #开启网页访问
  stats realm Haproxy\ Statistics
  stats auth admin:admin
  stats admin if TRUE

启动服务

$ systemctl enable --now haproxy.service
$ systemctl status haproxy.service
● haproxy.service - HAProxy Load Balancer
   Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2024-06-21 12:00:15 CST; 1min 13s ago
 Main PID: 18700 (haproxy-systemd)
   CGroup: /system.slice/haproxy.service
           ├─18700 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
           ├─18701 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
           └─18702 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds

Jun 21 12:00:15 OBHA-T2 systemd[1]: Stopped HAProxy Load Balancer.
Jun 21 12:00:15 OBHA-T2 systemd[1]: Started HAProxy Load Balancer.
Jun 21 12:00:15 OBHA-T2 haproxy-systemd-wrapper[18700]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds

安装keepalived

安装keepalived

两台机器都采用相同的操作

$ yum install -y keepalived

验证软件包是否被正确安装

$ rpm -qa | grep keepalived
keepalived-1.3.5-19.el7.x86_64
版本可以与本文不一致

准备keepalived的配置文件

备份2部机器上的keepalived的配置文件:

$ mv /etc/keepalived/keepalived.conf{,.bak}

创建OBHA-T1 上的keepalived 配置文件/etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
    router_id OBHA-T1
}
vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 5 
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state MASTER
    interface ens192
    mcast_src_ip 192.168.1.33
    virtual_router_id 35
    priority 101
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass OB_HA_AUTH
    }
    virtual_ipaddress {
        192.168.1.35
    }
    track_script {
      chk_haproxy
} }

创建OBHA-T2 上的keepalived 配置文件/etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
    router_id OBHA-T1
}
vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 5 
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state MASTER
    interface ens192
    mcast_src_ip 192.168.1.34
    virtual_router_id 35
    priority 100
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass OB_HA_AUTH
    }
    virtual_ipaddress {
        192.168.1.35
    }
    track_script {
      chk_haproxy
} }
注意: 本节所述的配置文件中的interface指的是服务器的网卡名称,实际环境可能与本文有差异,以实际环境配置为准。 两部服务器上的keepalived的配置文件中virtual_router_id 的值必须相同。

准备keepalived的检测脚本

三台上的脚本一样,文件路径为/etc/keepalived/check_haproxy.sh

#!/bin/bash

err=0
for k in $(seq 1 3)
do
    check_code=$(pgrep haproxy)
    if [[ $check_code == "" ]]; then
        err=$(expr $err + 1)
        sleep 1
        continue
    else
        err=0
        break
    fi
done

if [[ $err != "0" ]]; then
    echo "systemctl stop keepalived"
    /usr/bin/systemctl stop keepalived
    exit 1
else
    exit 0
fi

为检测脚本添加执行权限

$ chmod +x /etc/keepalived/check_haproxy.sh

启动服务

两台机器上的操作相同

$ systemctl daemon-reload
$ systemctl enable --now keepalived

检查服务

$ systemctl status keepalived.service 
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2024-06-21 13:54:54 CST; 40s ago
  Process: 22784 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 22785 (keepalived)
   CGroup: /system.slice/keepalived.service
           ├─22785 /usr/sbin/keepalived -D
           ├─22786 /usr/sbin/keepalived -D
           └─22787 /usr/sbin/keepalived -D
$ ping -c 4 192.168.1.35
PING 192.168.1.35 (192.168.1.35) 56(84) bytes of data.
64 bytes from 192.168.1.35: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 192.168.1.35: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 192.168.1.35: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 192.168.1.35: icmp_seq=4 ttl=64 time=0.034 ms

--- 192.168.1.35 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.027/0.041/0.058/0.012 ms
$ telnet 192.168.1.35 2883
Trying 192.168.1.35...
Connected to 192.168.1.35.
Escape character is '^]'.
J
5.6.25AKE=@js'b=��.�E%(9%L3U5HIwmysql_native_password

最后成功连接

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2146630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通信工程学习:什么是POS无源光分配器

POS&#xff1a;无源光分配器 POS&#xff08;Passive Optical Splitter&#xff0c;无源光分配器&#xff09;是无源光网络&#xff08;Passive Optical Network, PON&#xff09;中的一个重要组成部分&#xff0c;它位于光线路终端&#xff08;OLT&#xff09;和光网络单元&a…

基于Spring Boot的能源管理系统+建筑能耗+建筑能耗监测系统+节能监测系统+能耗监测+建筑能耗监测

介绍 建筑节能监测系统是基于计算机网络、物联网、大数据和数据可视化等多种技术融合形成的一套节能监测系统。 系统实现了对建筑电、水、热&#xff0c;气等能源、资源消耗情况的实时监测和预警、动态分析和评估&#xff0c;为用户建立了科学、系统的节能分析方法&#xff0c…

你天天用微服务还不知道心跳检测机制是什么?

目录标题 1. 心跳检测机制概述2. 心跳检测的具体实现2.1 服务注册与发现示例&#xff1a;Eureka 2.2 心跳包的格式2.3 超时机制 3. 实战中的心跳检测3.1 服务发现与注册中心3.2 定时任务与超时机制3.3 集群管理与协调3.4 故障隔离与恢复 4. 监控与告警5. 具体示例&#xff1a;Z…

制作一个rabbitmq-sdk

目录结构 pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">&l…

VR全景摄影制作中的常见问题及解决方案

随着VR全景摄影技术的普及&#xff0c;越来越多的摄影师和企业开始尝试使用这种方式来展示产品、场景或服务。虽然VR全景摄影有着强大的视觉表现力和沉浸式体验&#xff0c;但在制作过程中也会遇到各种挑战。为了帮助大家更好地掌握VR全景摄影的制作技巧&#xff0c;今天给分享…

STM32 单片机最小系统全解析

STM32 单片机最小系统全解析 本文详细介绍了 STM32 单片机最小系统&#xff0c;包括其各个组成部分及设计要点与注意事项。STM32 最小系统在嵌入式开发中至关重要&#xff0c;由电源、时钟、复位、调试接口和启动电路等组成。 在电源电路方面&#xff0c;采用 3.3V 直流电源供…

【Bug解决】Nacos启动成功,但却无法访问(提示:无法访问此网站,192.168.10.88的响应时间过长)

项目场景&#xff1a; 在虚拟机上通过Docker创建Nacos容器&#xff0c;已经创建成功&#xff0c;查看Nacos启动日志也是成功。但通过端口号加8848/nacos&#xff08;如&#xff1a;http://IP:8848/nacos&#xff09;无法访问到Nacos管理页面。 愿意分析一&#xff1a; 先检查好…

MyISAM引擎介绍

文章目录 特点适用场景不足锁机制表级锁的类型锁的获取和释放锁的等待队列 示例共享锁排他锁READ LOCAL MyISAM是MySQL的一种存储引擎&#xff0c;它以其简单性和高速度而著称。在早期的MySQL版本中&#xff0c;MyISAM广泛使用&#xff0c;尤其是在那些以读操作为主的应用场景中…

Parallels Desktop 20(Mac虚拟机) v20.0.0 for Mac 最新破解版(支持M系列)

Parallels Desktop 20 for Mac 正式发布&#xff0c;完全支持 macOS Sequoia 和 Windows 11 24H2&#xff0c;并且在企业版中引入了全新的管理门户。 据介绍&#xff0c;新版本针对 Windows、macOS 和 Linux 虚拟机进行了大量更新&#xff0c;最大的亮点是全新推出的 Parallels…

6款好用的电脑监控软件推荐|2024电脑监控软件干货整理!

电脑监控软件成为了企业管理中不可或缺的工具&#xff0c;这些软件不仅能够帮助企业实时监控员工的工作状态&#xff0c;还能有效提升团队效率和保障数据安全。 本文将为您推荐六款2024年值得一试的电脑监控软件&#xff0c;每款软件都有其独特的亮点和优势&#xff0c;适合不…

【Java-线程池】

目录 什么是线程池&#xff1a; 线程池七大参数&#xff1a; 参数详细介绍&#xff1a; 1.核心线程数&#xff1a; 2.最大线程数&#xff1a; 3.线程存活时间&#xff1a; 4.时间单位&#xff1a; 5. 阻塞工作队列&#xff1a; 6.线程工厂&#xff1a; 7.拒绝策略&am…

青柠视频云——视频丢包(卡顿、花屏、绿屏)排查

一、问题说明 近期有客户反馈&#xff0c;接入平台的设备经常出来卡顿、花屏、录屏的情况&#xff0c;出现这样的场景很是尴尬。 客户是私有化部署在公网环境&#xff0c;于是我们联系客户&#xff0c;对问题进行追踪排查。 二、场景复现 我们现场情况确认的过程中&#xff0c;…

怎么理解机器学习与数据融合的集成?

在科技进步的浪潮中&#xff0c;数据的重要性日益成为共识。但数据本身&#xff0c;若不经过有效的整合与分析&#xff0c;其价值便难以充分发挥。本文将探讨如何通过集成数据融合与机器学习&#xff0c;提升预测和决策的准确性。将海量数据转化为富含洞察力的信息&#xff0c;…

腾讯云TDSQL数据库认证值得考吗?来看看TDSQL证书有什么用

国内市场上的数据库产品有不少&#xff0c;很多大企业都有自己的数据库产品&#xff0c;比如金仓的KingBase、华为的OpenGauss、阿里云的PolarDB、达梦DM数据库等等&#xff0c;腾讯云也有自己的数据库产品&#xff0c;叫做TDSQL数据库&#xff0c;TDSQL数据库有两个分支&#…

基于SpringBoot+定时任务实现地图上绘制车辆实时运动轨迹图

目录 1. 项目结构 2. Maven依赖配置 (pom.xml) 3. 实现后端服务 4. 配置文件 (application.properties) 5. 启动项目 6. 访问页面 实现基于北斗卫星的车辆定位和轨迹图的Maven工程&#xff08;使用模拟数据&#xff09;&#xff0c;我们将使用以下技术&#xff1a; Spri…

企业导师面对面,产教融合实训基地搭建人才成长快车道

产教融合实训基地是指以特定专业群为服务对象&#xff0c;由高职院校和企业双方共同投入、共同利用&#xff0c;并由若干实验实训室和模块产线组成的综合性实训基地。这一基地不仅具备工学结合的功能&#xff0c;还融合了教育、产业和科技创新的要素&#xff0c;形成了一种特殊…

食品检测与分类系统源码分享

食品检测与分类检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

Galileo与GLONASS信号类型

GLONASS的G1信号与G2信号是频分多址&#xff0c;用于标记卫星。

面向切面:单元测试、事务、资源操作

目录 一、单元测试二、事务2.1、概述2.1.1、编程式事务2.1.2、声明式事务 2.2、JdbcTemplate2.3、基于注解的声明式事务2.3.1、基本用例-实现注解式的声明事务2.3.2、事务属性&#xff1a;只读2.3.3、事务属性&#xff1a;超时2.3.4、事务属性&#xff1a;回滚策略2.3.5、事务属…

柯桥生活英语培训之“老顾客”在英语中通常有几种表达方式?

“老顾客”用英语怎么说&#xff1f;千万不要直接翻译成“old customer”&#xff0c;因为这会让人误以为是指年龄大的顾客。 “老顾客”在英语中通常有以下几种表达方式&#xff1a; regular customer 这是最常见的表达&#xff0c;强调顾客经常光顾。这里的“regular”强调的…