Springboot + Mysql8 separate read and write

In the actual production environment in order to ensure the stability of the database, we generally give hot backup database configured dual-mechanism, so that after the collapse of the master database, slave database can immediately switch to the master database, the data is copied from the way through the main from the main database synchronization to write the code to read and write separation of business code from the library (to get the main transactional database processing add, change, delete operations, and from a database query processing operations) to improve load capacity of concurrent database.
file

Here we use the latest version of Mysql database (8.0.16) combined SpringBoot achieve this complete step (a master-slave).

Mysql installation configuration

  • From the https://dev.mysql.com/downloads/mysql/download page to install mysql package, I am here to download the mysql8.0.16 Linux-Generic.

  • Ready to be used as two virtual machines installed mysql, and download the file mysql-8.0.16-linux-glibc2.12-x86_64.tar.xzuploaded to the server / app / mysql
    • 192.168.249.131 CENTOS7 main
    • 192.168.249.129 CENTOS7 from
  • Check firewall status, if you start you need to turn off the firewall
service firewalld status  ## 查看防火墙状态
service firewalld stop   ## 关闭防火墙
  • Using a command file to extract the tar file xz
    xz -d mysql-8.0.16-linux-glibc2.12-x86_64.tar.xz

  • Extracting installation package
    tar -xvf mysql-8.0.16-linux-gl-ibc2.12-x86_64.tar

  • Establishing in the data folder / app / mysql, for storing data

  • Create a mysql user and mysql user group
groupadd mysql                                  ## 创建用户组
useradd -g mysql -d /app/mysql mysql    ## 在用户组下创建mysql用户并授权相关目录
groupdel mysql                                  ## 删除用户组名(若报已存在相关用户组)
userdel mysql                                   ## 删除用户(若报已存在相关用户)
  • Initial installation mysql database
    ./mysql-8.0.16-linux-glibc2.12-x86_64/bin/mysqld --user=mysql --basedir=/app/mysql --datadir=/app/mysql/data --initialize

    2019-07-01T02:05:52.681626Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
    2019-07-01T02:05:52.681694Z 0 [System] [MY-013169] [Server] /app/mysql/mysql-8.0.16-linux-glibc2.12-x86_64/bin/mysqld (mysqld 8.0.16) initializing of server in progress as process 1479
    2019-07-01T02:05:52.681726Z 0 [ERROR] [MY-010338] [Server] Can't find error-message file '/app/mysql/share/errmsg.sys'. Check error-message file location and 'lc-messages-dir' configuration directive.
    2019-07-01T02:05:55.713747Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: xa6(H>rK/r<E
    2019-07-01T02:05:57.303240Z 0 [System] [MY-013170] [Server] /app/mysql/mysql-8.0.16-linux-glibc2.12-x86_64/bin/mysqld (mysqld 8.0.16) initializing of server has completed

    Note that, at this time will generate a default mysql temporary password, as indicated above, modifications need to be saved and then

  • Establish and increase service mysql execute permissions
    cp mysql-8.0.16-linux-glibc2.12-x86_64/support-files/mysql.server /etc/init.d/mysqld

  • Mysql modify the configuration file to add the following configuration vi /etc/my.cnf

    [mysqld]
    port=3306
    basedir=/app/mysql/mysql-8.0.16-linux-glibc2.12-x86_64
    datadir=/app/mysql/data
    socket=/tmp/mysql.sock
    symbolic-links=0
    
    [mysqld_safe]
    log-error=/app/mysql/data/log/error.log
    pid-file=/app/mysql/data/mysql.pid
    user=mysql
    tmpdir=/tmp
    character_set_server=utf8
    default-storage-engine=INNODB
    init_connect='SET NAMES utf8'
    
    !includedir /etc/my.cnf.d

    If the message log permission-related errors, create a correspondence log files, and user authorization to mysql
    chown -R mysql:mysql /app/mysql/data/log/error.log

  • Start mysql service
    service mysqld start

  • Mysql client software to establish the connection
    ln -s /app/mysql/mysql-8.0.16-linux-glibc2.12-x86_64/bin/mysql /usr/local/bin/mysql

  • Log in to change the password mysql
mysql -uroot -p密码       ## 登录 
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '000000';
  • Setting remote login
use mysql;
update user set host='%' where user='root' limit 1;
flush privileges;

Mysql configuration master-slave synchronization (the binlog)

Replication Works

  • Master data change records to the binary log (binary log), that is the profile log-bin specified file, which is called the binary log records events (binary log events) 
  • Master Slave log events read by the binary I / O threads and writes it to the log relay (relay log) 
  • Slave relay redo log events in the event log information of a relay in a local execution of a complete data is stored locally, in order to achieve the change reflected its own data (data reproduction)

Copy Requirements

  • Master server from the same operating system version and the number of bits 
  • Master and Slave versions of the database to be consistent 
  • Data in the database Master and Slave to be consistent 
  • Master to open the binary log, Master and Slave of server_id must be unique within the local area network

Configuration Steps

Master database (192.168.249.131)

  • Create a simultaneous users and authorized
CREATE USER 'slave'@'192.168.249.129' IDENTIFIED WITH 'mysql_native_password' BY '000000';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'192.168.249.129';
FLUSH PRIVILEGES;

Note the need to use when creating a user mysql_native_passwordencryption plug-in, otherwise the default will use caching_sha2_passwordencryption, so in sync when SSL is required to verify the identity, in order to facilitate simple, direct use of our mysql_native_passwordway

  • Modify the configuration /etc/my.cnf, add the following configuration, open binlog, and restart the mysql service
    [mysqld] # 开启二进制日志功能 log-bin=mysql-bin # 设置server_id,,注意在网段内要唯一 server-id=131 #(可选配置)要同步的数据库名,要同步多个数据库,就多加几个replicate-db-db=数据库名 binlog-do-db=mydb #(可选配置)要忽略的数据库 binlog-ignore-db=mysql

  • View primary server status
    show master status
    file

Note the inside of the parameters, in particular the first two and the Position File, from the configuration server (Slave) master-slave relationship will be used.

From the database (192.168.249.129)

  • Modify /etc/my.cnf, add the following configuration, and restart the service
[mysqld]
server-id=129
log-bin=mysql-bin
replicate-do-db=mydb
replicate-ignore-db=mysql
  • Master slave setting information, the synchronization position specified
stop slave;
change master to master_host='192.168.249.131',master_user='slave',master_password='000000',master_log_file='mysql-bin.000001',master_log_pos=155;
start slave;

Parameters:
MASTER_HOST = '192.168.249.131' IP address ## Master
user master_user = 'slave' ## is used to synchronize data (in the Master authorized user)
master_password = '000000' ## the user's password synchronization data
master_port = 3306 ##-port Master database services
masterlogfile = 'mysql-bin.000001' ## designated Slave which log file read from start to copy the data (the results of the command of the file field on the Master)
masterlogpos = 155 from which ## POSITION No. starts reading (Position execution result of the command field on the master)
masterconnectretry = 30 from the master ## is re-established connection, if the connection establishment fails, try again after long intervals. Seconds, with a default of 60 seconds, the synchronous delay tuning parameters.

  • View from the server status
    show slave status\G;

    file

So far from complete master database level configuration.

SpringBoot configuration separated from the master reader

Observe the main mode from the following rules:
master database only perform INSERT, UPDATE, DELETEoperation
executed only from a database SELECToperation

我们这里使用开源项目[dynamic-datasource-spring-boot-starter](https://gitee.com/baomidou/dynamic-datasource-spring-boot-starter/wikis/)作为读写分离的工具包

Instructions

  • Establishment of a simple user data table in the primary database mydb, automatically synchronized from the built database
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`position` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  • The introduction of its dependencies
<dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>2.0.1</version>
       </dependency>

       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
           <version>2.5.5</version>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>8.0.15</version>
       </dependency>

       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <optional>true</optional>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>

   </dependencies>
  • Configuration data source
spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后再为匹配到指定数据源时候回抛出异常,不启动会使用默认数据源.
      datasource:
        master:
          type: com.zaxxer.hikari.HikariDataSource
          url: jdbc:mysql://192.168.249.131:3306/mydb?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: '000000'
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave_1:
          type: com.zaxxer.hikari.HikariDataSource
          url: jdbc:mysql://192.168.249.129:3306/mydb?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: '000000'
          driver-class-name: com.mysql.cj.jdbc.Driver
  • Start scanning type package inlet was added mybatis
@SpringBootApplication@MapperScan("com.jianzh5.dynamic.mapper")
public class DynamicDatsourceBootstrap {    
    public static void main(String[] args) {        
        SpringApplication.run(DynamicDatsourceBootstrap.class, args);
    }
}
  • The establishment of the entity class User
@Data
public class User {
    private int id;
    private String account;
    private String name;
    private String position;
}
  • Establish mapper interface files, two new methods addUser(User user),getById(int id)
public interface UserDao {
    @Insert("INSERT INTO user(account, name, position) VALUES(#{account}, #{name}, #{position})")
    @Options(useGeneratedKeys = true,keyProperty = "id")
    int addUser(User user);

    @Select("SELECT * FROM user WHERE id = #{id}")
    User getById(int id);
}
  • Service to establish service level associated implementation
public interface UserService {
        int addUser(User user);
        User getById(int id);
}
@Service
public class UserServiceImpl implements UserService {
        @Resource
        private UserDao userDao;

        @Override
        public int addUser(User user) {
            return userDao.addUser(user);
        }
        @DS("slave")
        @Override
        public User getById(int id) {
            return userDao.getById(id);
        }
}

Since the configuration of the data source primary: master, the default action for execution from the primary library, using annotations @DSswitching data sources, this can also be directly used for annotation class files, while there is a method based on the annotation on annotation priority.

  • Write unit tests for testing

    public class UserServiceTest extends DynamicDatsourceBootstrapTests {
        @Autowired
        private UserService userService;
        @Test
        public void testAddUser(){
            User user = new User();
            user.setName("李四");
            user.setAccount("sili");
            user.setPosition("JAVA开发工程师");
            int i = userService.addUser(user);
            System.out.println(user);
        }
        @Test
        public void testGetById(){
            int id = 4;
            User user = userService.getById(id);
            Assert.assertEquals("sanzhang",user.getAccount());
        }
    }
  • Execution log by observation, that read and write the database will be switched according to @DS annotations, far from the main completion Springboot integrated database separate read and write.

Please pay attention to individual public number: JAVA Rizhilu

Guess you like

Origin www.cnblogs.com/jianzh5/p/11654501.html