Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御

MySQL读写分离&Mybatis基础知识SQL注入

一、什么是MySQL高可用

主从复制。
主(master)核心数据访问,负责读和写
备(slave)主挂了,主服务器的备胎。
mysql服务器集群。一主一备、一主多备、多主多备。

备机一般只能有读的权限。
主机有读写权限。

读写分离会产生数据同步问题。
mysql 做集群

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第1张图片

二、mysql主从复制

mysql主从复制作用::读写分离(mycat)、数据备份、高可用、集群。
mysql主从复制原理:二进制sql执行文件。

只需要将主的二进制sql执行文件,往备机上执行一遍就实现了同步了。
同步是有延迟的,但是可以忽略不计。
还会有重试机制。

三、mysql主从复制配置 集群配置

mysql主从复制配置步骤:
1、配置主节点信息(server_id = ) 也就是配置那台是主机,唯一标识
2、设置从服务器读取账号的权限
3、同步

第一步:进入linux目录下的etc目录,打开mysql的配置文件 my.cnf
第二步:修改主服务器的my.cnf文件 vi /etc/my.cnf 新增一下内容
       server_id = 177 ### 服务器的id  
       ### 这里最好是你服务器id后面三位数
       log-bin=mysql-bin ###开启日志文件
配置踩的坑 
注意 配置一定要放在mysqld 下面,放在mysqld_safe下面配置没用
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

### mysql master conf
server_id=128
log-bin=mysql-bin

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid  
第三步:重启mysql 服务器 命令: service mysqld restart
       登录你主服务器的mysql 查看当前配置是否配置成功。

SHOW VARIABLES LIKE 'server_id' -- 查看服务器id是否配置成功

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第2张图片

第四步:查询主服务器状态:
    show master status -- 查看主服务器状态

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第3张图片

第五步:开始配置从服务器 打开etc目录下面的my.cnf文件,
在[mysql]下面添加如下。并重启mysql服务器
命令:service mysqld restart

server_id=129  # 配置的唯一id
log-bin=mysql-bin # 开启日志
binlog_do_db=test # 需要同步的数据库
第六步 主服务器给从服务器设置账号,分配权限  分配权限和账号
    在主服务器执行

GRANT REPLICATION SLAVE ON . to ‘mysync’@’%’ identified by ‘123456’;

第七步:在从服务器开启同步,开启同步之前,先要关闭同步
sql:

stop slave – 先停止同步

change master to master_host=’192.168.184.128’,master_user=’mysync’,master_password=’123456’,
master_log_file=’mysql-bin.000004’,master_log_pos=378; – 同步命令,在从服务器执行,同步文件是

start slave – 再开启同步

– 检测是否同不成功

show slave status

如图:

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第4张图片

注意点:
Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第5张图片


Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第6张图片

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第7张图片

四、 读写分离实现mycat

数据库负载均衡的好处:
    好处就是:不暴露本来的ip地址。

如图所示。 读写分离 大概流程图

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第8张图片

mysql反向代理。使用mycat来实现读写分离:

第一步:先配置好mycat  使用的数据库是weibo_simple。
    找到mycat的conf目录,找到 server.xml文件。

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第9张图片

第二步:配置好schema.xml文件,直接把下面copy进去。


<mycat:schema xmlns:mycat="http://org.opencloudb/">
    
    <schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
        <table name="t_users" primaryKey="user_id" dataNode="dn1" rule="rule1"/>
        <table name="t_message" type="global" primaryKey="messages_id" dataNode="dn1" />
    schema>
<dataNode name="dn1" dataHost="jdbchost" database="weibo_simple" />

    <dataHost name="jdbchost" maxCon="1000" minCon="10" balance="1"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"
                slaveThreshold="100">
         <heartbeat>select user()heartbeat>  
        <writeHost host="hostMaster" url="192.168.184.128:3306" user="root" password="123456">
        writeHost>
        <writeHost host="hostSlave" url="192.168.184.129:3306" user="root" password="123456"/>
    dataHost>

mycat:schema>
配置如图:

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第10张图片

第三步:配置rule.xml  直接全部复制进去



<mycat:rule xmlns:mycat="http://org.opencloudb/">
     <tableRule name="rule1">
        <rule>
            <columns>user_idcolumns>
            <algorithm>func1algorithm>
        rule>
    tableRule>
    <function name="func1" class="org.opencloudb.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txtproperty>
    function>
mycat:rule>
第四步:    把log4j level改成debug

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第11张图片

第五步:进行连接启动:

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第12张图片

使用窗口进行连接

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第13张图片

这个时候mycat会虚拟化出一个数据库叫mycat,
也是你刚刚配置同步的数据库。

这里写图片描述

这样三个库,就可以实现了同步了。
使用了中间件mycat同步很简单。

Java架构学习(二十二)mysql主从复制概念&读写分离概念&mysql集群搭建&读写分离实现使用中间件mycat实现&mybatis入门&sql注入防御_第14张图片


五、mybatis入门

mybatis是一个orm框架,表示对象关系映射。
mybatis是对jdbc的一种轻量级封装。

mybatis与hibernate区别?
答:mybatis是以sql语句得到对象。
   hibernate是通过对象得到sql

六、mybatis环境搭建流程

mybatis 配置文件 -- 配置mybatis 的sql文件
加载配置文件
建立一个mybatis.xml文件。

七、sql注入

之前web安全已经说了:
模拟请求:token令牌解决,加验证码是防止机器人。
防盗链:根据请求头referens,写个拦截器解决。
xss攻击:是通过写过滤器解决,将请求转换程html来解决。

什么是sql注入? or 1=1;
答:就是进行sql拼接来进行sql注入的。
解决方案:通过sql预编译来解决。不使用字符串拼接的方式。
    预编译就是通过?问号来传参的。

sql注入代码:
可以查找所有的用户。
package com.leeue.test;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
    String username = " xxx' OR 1='1";
    String password = "12345";
    String sql = "SELECT id,username FROM user_table WHERE " + "username='" + username + "'AND " + "password='"
                    + password + "'";
    Class.forName("com.mysql.jdbc.Driver");
    Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");
    PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
    System.out.println(stat.toString());
    ResultSet rs = stat.executeQuery();
    while (rs.next()) {
    String id = rs.getString(1);
    String name = rs.getString(2);
    System.out.println("id:" + id + "---name:" + name);
    }
}
}
防御sql注入代码: 通过问号来传参
package com.leeue.test;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
    String username = " xxx' OR 1='1";
    String password = "12345";
    String sql = "SELECT id,username FROM user_table WHERE username=? AND password=?";
    Class.forName("com.mysql.jdbc.Driver");
    Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");


    PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
    stat.setString(1, username);
    stat.setString(2, password);
    System.out.println(stat.toString());
    ResultSet rs = stat.executeQuery();
    while (rs.next()) {
    String id = rs.getString(1);
    String name = rs.getString(2);
    System.out.println("id:" + id + "---name:" + name);
    }
}
}
通过注释的方式来注入:
package com.leeue.test;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

public class TestSql {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
    String username = "xxx'or 1=1  -- ";
    String password = "12345";
/*  String sql = "SELECT id,username FROM user_table WHERE username=? AND password=?";*/
    String sql = "SELECT id,username FROM user_table WHERE " + "username='" + username + "'AND " + "password='"
            + password + "'";
    Class.forName("com.mysql.jdbc.Driver");
    Connection con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "12345");


    PreparedStatement stat = (PreparedStatement) con.prepareStatement(sql);
    /*stat.setString(1, username);
    stat.setString(2, password);*/
    System.out.println(stat.toString());
    ResultSet rs = stat.executeQuery();
    while (rs.next()) {
    String id = rs.getString(1);
    String name = rs.getString(2);
    System.out.println("id:" + id + "---name:" + name);
    }
}
}
sql语句:

SELECT id,username FROM user_table WHERE username=''or 1=1 xxx -- 'AND password='12345'

八、mybatis #与$区别?

mybatis # 可以防止sql注入
$ 能使用sql拼接。

你可能感兴趣的:(Java架构基础学习一)