MySQL8.0实现MHA高可用

一、简介

MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能。MHA 在监控到 master 节点故障时,会提升其中拥有最新数据的 slave 节点成为新的master 节点,在此期间,MHA 会通过于其它从节点获取额外信息来避免一致性方面的问题。MHA 还提供了 master 节点的在线切换功能,即按需切换 master/slave 节点。

   MHA 服务有两种角色, MHA Manager(管理节点)和 MHA Node(数据节点): MHA Manager:   通常单独部署在一台独立机器上管理多个 master/slave 集群(组),每个 master/slave 集群称作一个 application,用来管理统筹整个集群。 MHA node:   运行在每台 MySQL 服务器上(master/slave/manager),它通过监控具备解析和清理 logs 功能的脚本来加快故障转移。

 由上图我们可以看出,每个复制组内部和 Manager 之间都需要ssh实现无密码互连,只有这样,在 Master 出故障时, Manager 才能顺利的连接进去,实现主从切换功能

 二、工作原理

(1) 从宕机崩溃的 master 保存二进制日志事件(binlog events);

(2) 识别含有最新更新的 slave ;

(3) 应用差异的中继日志(relay log) 到其他 slave ;

(4) 应用从 master 保存的二进制日志事件(binlog events);

(5) 提升一个 slave 为新 master ;

(6) 使用其他的 slave 连接新的 master 进行复制。

三、MHA实现 

3.1环境准备

3.1.1准备四台虚拟机(均为centos 7.x )

3.1.2 更换yum源

3.1.3关闭防火墙,禁用SELinux

3.1.4 host配置 

在不同的机器上配置名字和IP地址 

机器名称IP配置服务角色备注
manager172.16.90.211manager控制器用于监控管理
master172.16.90.212数据库主服务器开启bin-log relay-log 关闭relay_log
slave1172.16.90.213数据库从服务器开启bin-log relay-log 关闭relay_log
slave2172.16.90.214数据库从服务器开启bin-log relay-log 关闭relay_log

 根据上表     名字要在不同的机器上分别输入如下命令

hostnamectl set-hostname managermastersalve1salve2

IP地址在其中一台输入即可 

[root@node4 ~]# cat >> /etc/hosts << EOF
> 172.16.90.111 manager
> 172.16.90.112 master
> 172.16.90.113 slave1
> 172.16.90.114 slave2
> EOF

3.2初始主节点 master 的配置

【master】 

 3.2.1解压·

  将mysql-8.0.18-1.el7.x86_64.rpm-bundle.tar包下载后复制到master虚拟机,再从这个虚拟机拷贝到slave1和slave2虚拟机的~目录

scp mysql-8.0.18-1.el7.x86_64.rpm-bundle.tar slave1:~

安装途中四个包,安装时可能会发现缺少依赖, 

 安装后我这里显示有个包需要移除

[rootnode2 MySQL]# yum remove mariadb-libs
3.2.2配置 master 文件

修改 master 的数据库配置文件来对其进行初始化配置

 在如图所示的地方插入两段话

vim /etc/my.cnf 

 3.3 slave 节点依赖的配置

主(master)配置后,从(slave1,slave2)也配置该文件:其他不变,从的server-id需要改为113,114,最后一行需要加上relay_log_purge = 0

三台机器配置完文件后,均重启服务

[root@master ~]# systemctl restart mysql.server 

查看有无密码 

 【master】

【slave】 两个slave机器都是相同的操作

免密登陆配置 

【master】

 在my.conf配置文件里插入一行

 

 3.4配置一主多从复制架构

【master】 

[root@node2 MySQL1]# mysql#先创建用户
(rootalocalhost) [(none)] >create user 'slave'@'172.16.90.%' identified with mysql_native_password by 'MySQL@123';
Query OK,0 rows affected(0.01 sec)#授权
(root@localhost) [(none)]>grant replication slave,replication client on *.* to 'slave'@'172.16.90.%';
Query OK, 0 rows affected, 1 warning (0.01 sec)

【slave】

[root@node2 MySQL1]# mysql(rootalocalhost)[(none)> change master to-> master host='172.16.90.112',-> master user='slave',-> master password='MySQL@123',-> master auto position=l;
Query OK,0 rows affected,2 warnings(0.10 sec)#开启主从同步
(rootalocalhost)[(none)> start slave;
Query OK,0 rows affected (0.00 sec)
(rootalocalhost)[(none)> show slave status \G
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 172.16.90.212Master_User: slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000002Read_Master_Log_Pos: 712Relay_Log_File: relay-log.000002Relay_Log_Pos: 925Relay_Master_Log_File: mysql-bin.000002Slave_IO_Running: YesSlave_SQL_Running: Yes
...

3.5安装配置MHA

3.5.1在 master 上进行授权  

 在所有 Mysql 节点授权拥有管理权限的用户可在本地网络中有其他节点上远程访问。

先创建用户再授权 

 3.5.2准备ssh互通环境

MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。接下来我们需要对四个节点进行设置生成密钥对,都拷贝到管理(master)节点

[root@all ~]# ssh-keygen -f ~/.ssh/id_rsa -P '' -q[root@all ~]# ssh-copy-id manager#拷贝免密钥
[root@node1 ~]# scp ~/.ssh/authorized_keys master:~/.ssh/
root@node2's password: 
authorized_keys             100% 1598     3.4MB/s   00:00   [root@node1 ~]# scp ~/.ssh/authorized_keys slave1:~/.ssh/
root@node3's password: 
authorized_keys             100% 1598     2.9MB/s   00:00  [root@node1 ~]# scp ~/.ssh/authorized_keys slave2:~/.ssh/
root@node4's password: 
authorized_keys             100% 1598     2.9MB/s   00:00                                    

验证免密钥登陆(每个机器都要验证,第一次登陆需要手动输入yes,后面就不需要了)
[root@node4 ~]# for i in manager master slave1 slave2;do ssh $i hostname;done

3.5.3 安装 MHA 包

安装包下载地址:

mha官网:https://code.google.com/archive/p/mysql-master-ha/

github下载地址:

https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58

Manager节点需要另外多安装一个包(manager和node ) ,MHA的Node依赖于perl-DBD-MySQL,所以配置epel源。

【manager】下载两个包,把其中一个拷贝给其他节点

[root@node1 ~]# wget -c https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
[root@node1 ~]# wget -c https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm

 【all】:所有的机器

[root@node1 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@node1 ~]# yum install mha4mysql-*.rpm

  【master】

由于直接安装存在依赖缺失和版本不一致问题,最后从mysql官网上下载了yum源文件(mysql84-community-release-el7-1.noarch.rpm),这里我就不具体写是怎么下载的了,大家去mysql官网找找

下载源到虚拟机后,拷贝到其他三个节点

 拷贝后先安装一下源,再安装node 

yum install mysql84-community-release-el7-1.noarch.rpmyum install mha4mysql-node-0.58-0.el7.centos.norach.rpm

 【slave】同理

yum install mysql84-community-release-el7-1.noarch.rpmyum install mha4mysql-node-0.58-0.el7.centos.norach.rpm

【manager】同理,不过需要多安装一个manager包

yum install mysql84-community-release-el7-1.noarch.rpmyum install mha4mysql-node-0.58-0.el7.centos.norach.rpm mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

 3.5.4 MHA配置

 Manager 节点需要为每个监控的 master/slave 集群提供一个专用的配置文件,而所有的 master/slave 集群也可共享全局配置。全局配置文件默认为/etc/masterha_default.cnf,其为可选配置。如果仅监控一组 master/slave 集群,也可直接通过 application 的配置来提供各服务器的默认配置信息。

3.5.5 定义 MHA 管理配置文件

创建一个目录存放MHA,方便管理 

创建配置文件目录
mkdir /etc/mha
创建日志目录
mkdir -p /var/log/mha/app1vim /etc/mha/app1.cnf
[server default] 			
user=mhaadmin 				
password=Mha@1234 			
manager_workdir=/var/log/mha/app1 		
manager_log=/var/log/mha/app1/manager.log 	
ssh_user=root 				
repl_user=slave				
repl_password=MySQL@123
ping_interval=1 			
[server1] 					
hostname=172.16.90.112	 	
ssh_port=22 				
candidate_master=1 			
[server2]
hostname=172.16.90.113
ssh_port=22
candidate_master=1
[server3]
hostname=172.16.90.114
ssh_port=22
candidate_master=1检查文件有无特殊字符
cat -v /etc/mha/app1.cnf
3.5.6 检测节点
1)检测各节点间 ssh 互信通信配置是否 ok
[root@node1 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
...
Wed Nov 24 11:36:56 2021 - [debug]  Connecting via SSH from root@172.16.90.212(172.16.90.212:22) to root@172.16.90.213(172.16.90.213:22)..
Wed Nov 24 11:36:56 2021 - [debug]   ok.
...2)检查管理的MySQL复制集群的连接配置参数是否OK
[root@node1 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
...
Wed Nov 24 11:37:55 2021 - [info] Got exit code 0 (Not master dead).MySQL Replication Health is OK.

3.6 启动MHA

[root@node1 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
[1] 11457

查看一下 master 节点的状态:

[root@node1 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:11457) is running(0:PING_OK), master:172.16.90.212

查看监控日志

[root@node1 ~]# tail -f /var/log/mha/app1/manager.log
172.16.90.212(172.16.90.212:3306) (current master)+--172.16.90.213(172.16.90.213:3306)+--172.16.90.214(172.16.90.214:3306)Wed Nov 24 11:45:30 2021 - [warning] master_ip_failover_script is not defined.
Wed Nov 24 11:45:30 2021 - [warning] shutdown_script is not defined.
...
Wed Nov 24 11:45:30 2021 - [info] Starting ping health check on 172.16.90.212(172.16.90.212:3306)..
Wed Nov 24 11:45:30 2021 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
3.6.1 开发启动服务脚本

工作中启动太麻烦了,所以找了一个脚本作为启动服务

路径一样可以用,不一样得改

[root@node1 ~]  vim /etc/init.d/masterha_managerd
#!/bin/bash
# chkconfig: 35 80 20
# description: MHA management script.STARTEXEC="/usr/bin/masterha_manager --conf"
STOPEXEC="/usr/bin/masterha_stop --conf"
CONF="/etc/mha/app1.cnf"
process_count=`ps -ef |grep -w masterha_manager|grep -v grep|wc -l`
PARAMS="--ignore_last_failover"case "$1" instart)if [ $process_count -gt 1 ]thenecho "masterha_manager exists, process is already running"elseecho "Starting Masterha Manager"$STARTEXEC $CONF $PARAMS < /dev/null > /var/log/mha/app1/manager.log 2>&1 &fi;;stop)if [ $process_count -eq 0 ]thenecho "Masterha Manager does not exist, process is not running"elseecho "Stopping ..."$STOPEXEC $CONFwhile(true)doprocess_count=`ps -ef |grep -w masterha_manager|grep -v grep|wc -l`if [ $process_count -gt 0 ]thensleep 1elsebreakfidoneecho "Master Manager stopped"fi;;*)echo "Please use start or stop as first argument";;
esac
[root@node1 ~]  chmod +x /etc/init.d/masterha_managerd添加成启动服务:
[root@node1 ~]  chkconfig --add masterha_managerd
[root@node1 ~]  chkconfig masterha_managerd on
3.6.2 测试服务脚本

脚本和命令不能同时启动,可能会有问题,先关闭进程

开启脚本:
[root@node1 ~]  systemctl start masterha_managerd
[root@node1 ~]  systemctl status masterha_managerd
● masterha_managerd.service - SYSV: MHA management script.Loaded: loaded (/etc/rc.d/init.d/masterha_managerd; bad; vendor preset: disabled)
...停止脚本:
[root@node1 ~]# systemctl stop masterha_managerd
看进程:
[root@node1 ~]# ps -ef | grep -w masterha_manager
root      25856   1169  0 15:24 pts/0    00:00:00 grep --color=auto -w masterha_manager

 3.7 配置VIP

为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟ip,而不是使用keepalived来完成。

脑裂:由于互相争抢资源而导致得一种异常,检测不到对方存活信息

1.编写脚本

[root@node1 ~]  vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perluse strict;
use warnings FATAL => 'all';use Getopt::Long;my ($command,          $ssh_user,        $orig_master_host, $orig_master_ip,$orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
);my $vip = '172.16.90.210/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";GetOptions('command=s'          => \$command,'ssh_user=s'         => \$ssh_user,'orig_master_host=s' => \$orig_master_host,'orig_master_ip=s'   => \$orig_master_ip,'orig_master_port=i' => \$orig_master_port,'new_master_host=s'  => \$new_master_host,'new_master_ip=s'    => \$new_master_ip,'new_master_port=i'  => \$new_master_port,
);exit &main();sub main {print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";if ( $command eq "stop" || $command eq "stopssh" ) {my $exit_code = 1;eval {print "Disabling the VIP on old master: $orig_master_host \n";&stop_vip();$exit_code = 0;};if ($@) {warn "Got Error: $@\n";exit $exit_code;}exit $exit_code;}elsif ( $command eq "start" ) {my $exit_code = 10;eval {print "Enabling the VIP - $vip on the new master - $new_master_host \n";&start_vip();$exit_code = 0;};if ($@) {warn $@;exit $exit_code;}exit $exit_code;}elsif ( $command eq "status" ) {print "Checking the Status of the script.. OK \n";exit 0;}else {&usage();exit 1;}
}sub start_vip() {`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {return 0  unless  ($ssh_user);`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}sub usage {print"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}[root@node1 ~]  chmod +x /usr/local/bin/master_ip_failover 

注意脚本两个地方:网段和接口 

2、更改manager配置文件

[root@node1 ~]# vim /etc/mha/app1.cnf 
[server default]
添加:
master_ip_failover_script=/usr/local/bin/master_ip_failover

3、主库上,手工生成第一个vip地址

[root@node2 ~]# ifconfig eth0:1 172.16.90.210/24
注意:第一次需要在主库上手动配置vip
[root@node2 ~]# ifconfig -a |grep -A 2 "eth0:1"
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.16.90.210  netmask 255.255.255.0  broadcast 172.16.90.255ether 28:6e:d4:89:3b:3e  txqueuelen 1000  (Ethernet)

4、重启MHA

[root@node1 ~]# systemctl restart masterha_managerd

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

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

相关文章

记录 | WPF基础学习登录界面制作

目录 前言一、普通方式Step1 创建项目Step2 设计布局Step3 对剩余布局进行内容填充可执行代码下载 Step4 编写点击事件Step5 创建新WPF窗口Step6 简单写点Index内容Step7 跳转到Index当前代码下载 二、绑定方式绑定用户名【单向绑定】双向绑定代码提供 三、MVVM方式1&#xff1…

vivado 7 系列器件时钟

7 系列器件时钟 注释&#xff1a; 本章节以 Virtex -7 时钟源为例。 Virtex-6 的时钟资源与此类似。如果使用不同的架构&#xff0c;请参阅有关器件的 《时 钟资源指南》 [ 参照 40] 。 Virtex-6 和 Virtex-7 器件内含 32 个称为 BUFG 的全局时钟缓存。 BUFG 可满…

无须付费,安装即是完全版!

不知道大家有没有遇到过不小心删掉了电脑上超重要的文件&#xff0c;然后急得像热锅上的蚂蚁&#xff1f; 别担心&#xff0c;今天给大家带来一款超给力的数据恢复软件&#xff0c;简直就是拯救文件的“救星”&#xff01; 数据恢复 专业的恢复数据软件 这款软件的界面设计得特…

【图片合并转换PDF】如何将每个文件夹下的图片转化成PDF并合并成一个文件?下面基于C++的方式教你实现

医院在为患者进行诊断和治疗过程中&#xff0c;会产生大量的医学影像图片&#xff0c;如 X 光片、CT 扫描图、MRI 图像等。这些图片通常会按照检查时间或者检查项目存放在不同的文件夹中。为了方便医生查阅和患者病历的长期保存&#xff0c;需要将每个患者文件夹下的图片合并成…

Racecar Gym 总结

1.Racecar Gym 简介 Racecar Gym 是一个基于 PyBullet 物理引擎 的自动驾驶仿真平台&#xff0c;提供 Gymnasium&#xff08;OpenAI Gym&#xff09; 接口&#xff0c;主要用于强化学习&#xff08;Reinforcement Learning, RL&#xff09;、多智能体竞速&#xff08;Multi-Ag…

基于微信小程序的医院预约挂号系统的设计与实现

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生…

智体链:大语言模型协作完成长上下文任务

25年1月来自Penn State U和谷歌云的论文“Chain of Agents: Large Language Models Collaborating on Long-Context Tasks”。 解决有效处理长上下文的挑战已成为大语言模型 (LLM) 的关键问题。出现了两种常见策略&#xff1a;1&#xff09;减少输入长度&#xff0c;例如通过检…

java s7接收Byte字节,接收word转16位二进制

1图&#xff1a; 2.图&#xff1a; try {List list getNameList();//接收base64S7Connector s7Connector S7ConnectorFactory.buildTCPConnector().withHost("192.168.46.52").withPort(102).withTimeout(1000) //连接超时时间.withRack(0).withSlot(3).build()…

机器学习在癌症分子亚型分类中的应用

学习笔记&#xff1a;机器学习在癌症分子亚型分类中的应用——Cancer Cell 研究解析 1. 文章基本信息 标题&#xff1a;Classification of non-TCGA cancer samples to TCGA molecular subtypes using machine learning发表期刊&#xff1a;Cancer Cell发表时间&#xff1a;20…

Redis --- 使用HyperLogLog实现UV(访客量)

UV 和 PV 是网站或应用数据分析中的常用指标&#xff0c;用于衡量用户活跃度和页面访问量。 UV (Unique Visitor 独立访客)&#xff1a; 指的是在一定时间内访问过网站或应用的独立用户数量。通常根据用户的 IP 地址、Cookies 或用户 ID 等来唯一标识一个用户。示例&#xff1…

大学资产管理系统中的下载功能设计与实现

大学资产管理系统是高校信息化建设的重要组成部分&#xff0c;它负责记录和管理学校内所有固定资产的信息。随着信息技术的发展&#xff0c;下载功能成为提高资产管理效率的关键环节之一。 系统架构的设计是实现下载功能的基础。一个良好的系统架构能够确保数据的高效传输和存储…

Vue 3 中的 el-tooltip 详解:语法、示例及与其他框架对比

目录 前言1. 基本知识2. 实战Demo 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 1. 基本知识 el-tooltip 是 Element Plus&#xff08;Vue 3 组件库&#xff09;中的一个用于提示的组件&#xff0c;它可以在…

Day 31 卡玛笔记

这是基于代码随想录的每日打卡 491. 非递减子序列 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0…

docker /var/lib/docker/overlay2目录把磁盘空间占满问题

1、查看服务器磁盘空间 df -h果然100%了,docker系统文件把磁盘空间占满了。 2、进入overlay2目录&#xff0c;查找那个容器工作目录占用最高 cd /var/lib/docker/overlay2du -h --max-depth1详见下图 好家伙占用110G&#xff01;复制目录名称2c3c48ccac533c5d4a366d45a19bb9…

02vue3实战-----项目目录详解

02vue3实战-----项目目录详解 1.目录完整结构2.extensions.json文件3.node_modules文件夹4.public文件夹5.src文件夹6.文件.gitignore7.文件env.d.ts8.文件index.html9.文件package-lock.json和文件package.json10.文件README.md11.文件vite.config.ts12.文件tsconfig.json和文…

【蓝桥杯嵌入式】4_key:单击+长按+双击

全部代码网盘自取 链接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码&#xff1a;3ii2 1、电路图 将4个按键的引脚设置为input&#xff0c;并将初始状态设置为Pull-up&#xff08;上拉输入&#xff09; 为解决按键抖动的问题&#xff0c;我们…

qt部分核心机制

作业 1> 手动将登录项目实现&#xff0c;不要使用拖拽编程 并且&#xff0c;当点击登录按钮时&#xff0c;后台会判断账号和密码是否相等&#xff0c;如果相等给出登录成功的提示&#xff0c;并且关闭当前界面&#xff0c;发射一个跳转信号&#xff0c;如果登录失败&#…

Spring Boot启动内嵌tocmat原理

要研究Spring Boot启动内嵌tomcat的原理&#xff0c;就需要先了解一下Spring Boot自动配置的过程&#xff0c;首先简要的梳理一下springboot自动配置的步骤。 一、SpringBoot自动配置 当SpringBoot应用启动时&#xff0c;EnableAutoConfiguration注解被激活&#xff0c;该注解…

【论文阅读】Comment on the Security of “VOSA“

Comment on the Security of Verifiable and Oblivious Secure Aggregation for Privacy-Preserving Federated Learning -- 关于隐私保护联邦中可验证与遗忘的安全聚合的安全性 论文来源摘要Introduction回顾 VOSA 方案对VOSA不可伪造性的攻击对于类型 I 的攻击对于类型 II 的…

idea隐藏无关文件

idea隐藏无关文件 如果你想隐藏某些特定类型的文件&#xff08;例如 .log 文件或 .tmp 文件&#xff09;&#xff0c;可以通过以下步骤设置&#xff1a; 打开设置 在菜单栏中选择 File > Settings&#xff08;Windows/Linux&#xff09;或 IntelliJ IDEA > Preference…