美文网首页
sharding-jdbc + druid 实现mysql 主备

sharding-jdbc + druid 实现mysql 主备

作者: 乘以零 | 来源:发表于2018-06-11 16:50 被阅读0次

    功能需求

    1. master 正常时 所有请求router到master;
    2. master不正常时,DQL路由到slaves(slaves 会进行负载均衡,算法自定),DML DDL等抛异常;

    直接贴代码 简单点

    Demo.java

    package com.yiwugou.demo.sharding;
    
    import java.sql.SQLException;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.sql.DataSource;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.alibaba.druid.filter.Filter;
    import com.alibaba.druid.pool.DruidDataSource;
    
    import io.shardingsphere.core.api.MasterSlaveDataSourceFactory;
    import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration;
    
    public class Demo {
        private static YiwugouConfig config = new YiwugouConfig();
    
        public static void main(String[] args) throws Exception {
    
            DataSource masterSlaveDataSource = initMasterSlaveDataSource();
            DataSource dataSource = initYiwugouDataSource(masterSlaveDataSource);
            JdbcTemplate jdbcTemplate = initJdbcTemplate(dataSource);
    
            for (int i = 0; i <= 100000; i++) {
                try {
                    List<Map<String, Object>> objs = jdbcTemplate.queryForList("select * from T_DEMO");
                    System.err.println(i + "=" + objs);
    
                    Thread.sleep(1000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // try {
                // jdbcTemplate.update("insert into T_DEMO (name) values ('abcd" + i
                // + "')");
                // System.err.println("execute=" + i);
                // Thread.sleep(1000L);
                // } catch (Exception e) {
                // e.printStackTrace();
                // }
            }
        }
    
        public static DataSource initYiwugouDataSource(DataSource dataSource) {
            YiwugouDataSource ds = new YiwugouDataSource(dataSource, config);
            return ds;
        }
    
        public static DataSource initMasterSlaveDataSource() throws SQLException {
            DataSource ds_72 = initDataSource("com.mysql.jdbc.Driver", "jdbc:mysql://10.6.2.72:3306/demo", "root",
                    "admin123");
            DataSource ds_127 = initDataSource("com.mysql.jdbc.Driver", "jdbc:mysql://127.0.0.1:3306/demo", "root", "");
    
            Map<String, DataSource> dataSourceMap = new HashMap<>();
            dataSourceMap.put("ds_master", ds_127);
            dataSourceMap.put("ds_slave_0", ds_72);
            // dataSourceMap.put("ds_slave_1", slaveDataSource1);
    
            MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration("ds_master_slave",
                    "ds_master", Arrays.asList("ds_slave_0"));
    
            DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, masterSlaveRuleConfig,
                    new HashMap<String, Object>());
            return dataSource;
        }
    
        public static DataSource initDataSource(String driver, String url, String username, String password) {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driver);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setMaxActive(100);
            dataSource.setMinIdle(5);
    
            dataSource.setFailFast(true); // 重要 不然会卡住
            Filter yiwugouFilter = new YiwugouFilter(new Runnable() {
                @Override
                public void run() {
                    config.setAlived(false);
                }
            });
            dataSource.setProxyFilters(Arrays.asList(yiwugouFilter));
            // dataSource.setBreakAfterAcquireFailure(true);
            // dataSource.setAsyncInit(true);
            return dataSource;
        }
    
        public static JdbcTemplate initJdbcTemplate(DataSource dataSource) {
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            return jdbcTemplate;
        }
    
    }
    
    

    YiwugouConfig.java

    package com.yiwugou.demo.sharding;
    
    public class YiwugouConfig {
        private boolean isAlived = true;
    
        public boolean isAlived() {
            return isAlived;
        }
    
        public void setAlived(boolean isAlived) {
            this.isAlived = isAlived;
        }
    }
    

    YiwugouDataSource

    package com.yiwugou.demo.sharding;
    
    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.SQLFeatureNotSupportedException;
    import java.util.logging.Logger;
    
    import javax.sql.DataSource;
    
    import io.shardingsphere.core.api.HintManager;
    
    public class YiwugouDataSource implements DataSource {
        private DataSource dataSource;
    
        private YiwugouConfig config;
    
        public YiwugouDataSource(DataSource dataSource, YiwugouConfig config) {
            this.dataSource = dataSource;
            this.config = config;
        }
    
        @Override
        public Connection getConnection() throws SQLException {
            if (config.isAlived()) {
                HintManager hintManager = HintManager.getInstance();
                hintManager.setMasterRouteOnly();
            }
            Connection con = this.getDataSource().getConnection();
            return con;
    
        }
    
        @Override
        public Connection getConnection(String username, String password) throws SQLException {
            if (config.isAlived()) {
                HintManager hintManager = HintManager.getInstance();
                hintManager.setMasterRouteOnly();
            }
            Connection con = this.getDataSource().getConnection(username, password);
            return con;
        }
    
        private DataSource getDataSource() {
            return this.dataSource;
        }
    
        @Override
        public void setLoginTimeout(int timeout) throws SQLException {
            this.getDataSource().setLoginTimeout(timeout);
        }
    
        @Override
        public PrintWriter getLogWriter() throws SQLException {
            return this.getDataSource().getLogWriter();
        }
    
        @Override
        public void setLogWriter(PrintWriter pw) throws SQLException {
            this.getDataSource().setLogWriter(pw);
        }
    
        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            return this.getDataSource().unwrap(iface);
        }
    
        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            return this.getDataSource().isWrapperFor(iface);
        }
    
        @Override
        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
            return this.getDataSource().getParentLogger();
        }
    
        @Override
        public int getLoginTimeout() throws SQLException {
            return this.getDataSource().getLoginTimeout();
        }
    }
    
    

    YiwugouFilter.java

    package com.yiwugou.demo.sharding;
    
    import java.sql.SQLException;
    
    import com.alibaba.druid.filter.FilterAdapter;
    import com.alibaba.druid.filter.FilterChain;
    import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
    import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
    import com.alibaba.druid.proxy.jdbc.StatementProxy;
    
    public class YiwugouFilter extends FilterAdapter {
        public YiwugouFilter(Runnable runnable) {
            this.runnable = runnable;
        }
    
        private Runnable runnable;
    
        @Override
        public void preparedStatement_addBatch(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
            try {
                super.preparedStatement_addBatch(chain, statement);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public boolean preparedStatement_execute(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
            try {
                return super.preparedStatement_execute(chain, statement);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public ResultSetProxy preparedStatement_executeQuery(FilterChain chain, PreparedStatementProxy statement)
                throws SQLException {
            try {
                return super.preparedStatement_executeQuery(chain, statement);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int preparedStatement_executeUpdate(FilterChain chain, PreparedStatementProxy statement)
                throws SQLException {
            try {
                return super.preparedStatement_executeUpdate(chain, statement);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public void statement_addBatch(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
            try {
                super.statement_addBatch(chain, statement, sql);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
            try {
                return super.statement_execute(chain, statement, sql);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
                throws SQLException {
            try {
                return super.statement_execute(chain, statement, sql, autoGeneratedKeys);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, int[] columnIndexes)
                throws SQLException {
            try {
                return super.statement_execute(chain, statement, sql, columnIndexes);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql, String[] columnNames)
                throws SQLException {
            try {
                return super.statement_execute(chain, statement, sql, columnNames);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int[] statement_executeBatch(FilterChain chain, StatementProxy statement) throws SQLException {
            try {
                return super.statement_executeBatch(chain, statement);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql)
                throws SQLException {
            try {
                return super.statement_executeQuery(chain, statement, sql);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
            try {
                return super.statement_executeUpdate(chain, statement, sql);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys)
                throws SQLException {
            try {
                return super.statement_executeUpdate(chain, statement, sql, autoGeneratedKeys);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int[] columnIndexes)
                throws SQLException {
            try {
                return super.statement_executeUpdate(chain, statement, sql, columnIndexes);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
        @Override
        public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, String[] columnNames)
                throws SQLException {
            try {
                return super.statement_executeUpdate(chain, statement, sql, columnNames);
            } catch (Exception e) {
                runnable.run();
                throw e;
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:sharding-jdbc + druid 实现mysql 主备

          本文链接:https://www.haomeiwen.com/subject/hjpheftx.html