`

spring配置数据库负载均衡

阅读更多
package com.hengyu.ticket.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by lgf on 2016/4/3.
 * 使用多台数据库服务区器负载
 */
public class CommonLoadBalancing {

    private static final String SERVER_CONFIG = "SERVER.JSON";
    public static String DB_DRIVER;
    public static String DB_PORT;
    public static String DB_USER_NAME;
    public static String DB_PASSWORD;
    public static String DB_URL;

    //选择服务器类型(线程安全)
    private static final ThreadLocal<String> SERVER_HOLDER = new ThreadLocal<>();

    //服务器类型
    private final static String SERVER_MASTER = "MASTER";
    private final static String SERVER_SLAVE = "SLAVE";

    //当前服务器的编号
    private static Integer CURRENT_INDEX = -1;
    //当前权重
    private static Integer CURRENT_WEIGHT = 0;
    //最大权重
    private static Integer MAX_WEIGHT = 0;
    //权重公约数
    private static Integer GCD_WEIGHT = 1;
    //最小公约数
    private static Integer MIN_WEIGHT = 1;
    //主服务器
    private static Server MASTER;
    //备用主服务器
    private static Server MASTER_RESERVED;
    //服务器集合
    public static final List<Server> servers = Collections.synchronizedList(new ArrayList<Server>());
    //脱机服务器集合
    private static final List<Server> down_servers = Collections.synchronizedList(new ArrayList<Server>());

    static {
        DBConfig.init();
    }

    //获取主服务器,备用主服务器
    public static Server getMaster() {
        if (MASTER.isDown()) {
            if (MASTER_RESERVED != null && !MASTER_RESERVED.isDown()) {
                return MASTER_RESERVED;
            } else {
                throw new RuntimeException("error:tow master is down!");
            }
        }
        return MASTER;
    }

    public static void setMaster(Server master) {
        CommonLoadBalancing.MASTER = master;
    }

    //添加服务器
    public static void addServer(Server server) {
        addServer(server, false);
    }

    //添加服务器
    public static void addServer(Server server, boolean isReload) {
        if (server == null) {
            throw new RuntimeException("error: server cant't not be null !");
        }
        int index = servers.size();
        if (server.getType() != null && SERVER_MASTER.equals(server.getType())) {
            MASTER = server;
        } else if (server.getType() == null) {
            server.setType(SERVER_SLAVE);
        }
        servers.add(server);
        if (isReload) {
            initOrReload();
        }
    }

    //添加服务器
    public static void addServer(List<Server> servers) {
        for (int i = 0; i < servers.size(); i++) {
            Server server = servers.get(i);
            addServer(server);
        }
        CommonLoadBalancing.initOrReload();
    }

    //查找权重,计算权重公约数

    public synchronized static void initOrReload() {
        for (Server server : servers) {
            if (server == null || server.isDown()) {
                continue;
            }
            if (server.getWeight() > MAX_WEIGHT) {
                MAX_WEIGHT = server.getWeight();
            }
            if (server.getWeight() < MIN_WEIGHT) {
                MIN_WEIGHT = server.getWeight();
            }
        }
        if (MASTER == null) {
            MASTER = servers.get(0);
            MASTER.setType(SERVER_MASTER);
        }
        GCD_WEIGHT = gcd(servers);
    }

    //获取权重公因数
    public static int gcd(List<Server> servers) {
        if (servers == null || servers.size() == 0) {
            return 1;
        }
        int min = servers.get(0).getWeight();

        for (int i = 0; i < servers.size(); i++) {
            Server server = servers.get(i);
            if (server.getWeight() < min) {
                min = server.getWeight();
            }
        }
        while (min >= 1) {
            boolean isCommon = true;
            for (int i = 0; i < servers.size(); i++) {
                Server server = servers.get(i);
                if (server.getWeight() % min != 0) {
                    isCommon = false;
                    break;
                }
            }
            if (isCommon) {
                break;
            }
            min--;
        }
        return min<1?1:min;
    }


    //轮询服务器
    public static Server getServer() {
        int count = 0;
        int size = servers.size();
        if (size == 0 || getServerType().equals(SERVER_MASTER)) {
            return getMaster().addAccessCount();
        }
        clearServerHolder();
        while (true) {
            CURRENT_INDEX = (CURRENT_INDEX + 1) % size;
            if (CURRENT_INDEX == 0) {
                CURRENT_WEIGHT = CURRENT_WEIGHT - GCD_WEIGHT;
                if (CURRENT_WEIGHT <= 0) {
                    CURRENT_WEIGHT = MAX_WEIGHT;
                }
            }
            Server server = servers.get(CURRENT_INDEX);
            if (server != null && server.getWeight() >= CURRENT_WEIGHT && !server.isDown) {
                return server.addAccessCount();
            }
            if (count >= size) {
                return getMaster().addAccessCount();
            }
            count++;
        }
    }

    public static List<Server> getServers() {
        return servers;
    }

    public static void setMasterReserved(Server masterReserved) {
        CommonLoadBalancing.MASTER_RESERVED = masterReserved;
    }

    public static List<Server> getDown_servers() {
        return down_servers;
    }

    public static void setServerType(boolean isReadOnly) {
        if (isReadOnly) {
            SERVER_HOLDER.set(SERVER_SLAVE);
        } else {
            SERVER_HOLDER.set(SERVER_MASTER);
        }
    }

    public static void clearServerHolder() {
        SERVER_HOLDER.set(SERVER_SLAVE);
    }

    public static String getServerType() {
        String type = SERVER_HOLDER.get();
        if (type == null || type.equals(SERVER_SLAVE)) {
            return SERVER_SLAVE;
        }
        return SERVER_MASTER;
    }

    public static class Server {
        //服务器编号
        private String id;
        //服务器索引
        private Integer index;
        ///服务器ip
        private String ip;
        //权重
        private int weight;
        //类型,主从
        private String type;
        //用户名
        private String username;
        //密码
        private String password;
        //端口
        private String port;
        //url链接
        private String url;
        //访问数量
        private Integer accessCount = 0;
        //是否脱机
        private boolean isDown;

        public Server() {

        }

        @Override
        public String toString() {
            return "Server{type='" + type + '\'' + ", ip='" + ip + '\'' + ", weight=" + weight + ", accessCount=" + accessCount + '}';
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getPort() {
            return port;
        }

        public void setPort(String port) {
            this.port = port;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public Integer getIndex() {
            return index;
        }

        public void setIndex(Integer index) {
            this.index = index;
        }

        public Server(String ip, int weight) {
            this.ip = ip;
            this.weight = weight;
        }

        public int getAccessCount() {
            return accessCount;
        }

        public void setAccessCount(int accessCount) {
            this.accessCount = accessCount;
        }

        public Server addAccessCount() {
            synchronized (this.accessCount) {
                this.accessCount++;
                return this;
            }
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public int getWeight() {
            if (weight < 1) {
                weight = 1;
            }
            return weight;
        }

        public void setWeight(int weight) {
            if (weight < 1) {
                weight = 1;
            }
            this.weight = weight;
        }

        public boolean isDown() {
            return isDown;
        }

        public void setDown(boolean down) {
            isDown = down;
        }
    }

    //数据库配置
    public static class DBConfig {
        /*
        * { "username": "root", "password": "admin", "port": "3306", "driver": "com.mysql.jdbc.Driver"
        * , "url": "jdbc:mysql://${host}:${prot}/ticket?characterEncoding=utf8", "master": [ "127.0.0.1" ],
        * "slave": [ "192.168.0.10 -w100", "192.168.0.11 -w50" ] }
        *
        * */

        //初始化
        public static void init() {
            InputStream in = null;
            try {
                in = Thread.currentThread().getContextClassLoader().getResourceAsStream(SERVER_CONFIG);
                if (in == null) {
                    throw new RuntimeException("error:" + SERVER_CONFIG + " cat't not be null");
                }
                byte[] bs = new byte[in.available()];
                in.read(bs);
                JSONObject base = JSON.parseObject(new String(bs));
                DB_USER_NAME = base.get("username") == null ? "" : base.get("username").toString();
                DB_PASSWORD = base.get("password") == null ? "" : base.get("password").toString();
                DB_URL = base.get("url") == null ? "" : base.get("url").toString();
                DB_DRIVER = base.get("driver") == null ? "" : base.get("driver").toString();
                DB_PORT = base.get("port") == null ? "" : base.get("port").toString();
                List<String> masters = JSON.parseArray(base.get("master").toString(), String.class);
                List<String> slaves = null;
                if (base.get("slave") != null) {
                    slaves = JSON.parseArray(base.get("slave").toString(), String.class);
                }
                createServer(masters, slaves);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                }
            }
        }

        //创建服务器
        public synchronized static void createServer(List<String> masters, List<String> slave) {
            List<Server> servers = new ArrayList<>();
            int i = 0;
            if (masters != null) {
                //主服务器
                for (String info : masters) {
                    Server server = new Server();
                    server.setId(String.valueOf(i));
                    createServer(SERVER_MASTER, server, info);
                    server.setIndex(servers.size());
                    servers.add(server);
                    CommonLoadBalancing.MASTER = server;
                    if (i == 1) {
                        CommonLoadBalancing.MASTER_RESERVED = server;
                    }
                    i++;
                }
            }

            //从服务器
            if (slave != null) {
                for (String info : slave) {
                    Server sa = new Server();
                    sa.setId(String.valueOf(i));
                    createServer(SERVER_SLAVE, sa, info);
                    sa.setIndex(i);
                    servers.add(sa);
                    i++;
                }
            }
            CommonLoadBalancing.addServer(servers);
        }

        //创建服务器
        public static void createServer(String type, Server server, String info) {
            server.setUrl(DB_URL);
            server.setPort(DB_PORT);
            server.setUsername(DB_USER_NAME);
            server.setPassword(DB_PASSWORD);
            server.setType(type);
            String[] array = info.trim().split("\\s");
            int i = 0;
            for (String item : array) {
                if (item.startsWith("-w")) {
                    server.setWeight(Integer.parseInt(getConfigString(item, array, i)));
                } else if (item.startsWith("-u")) {
                    server.setUsername(getConfigString(item, array, i));
                } else if (item.startsWith("-p")) {
                    server.setPassword(getConfigString(item, array, i));
                } else if (item.startsWith("-P")) {
                    server.setPort(getConfigString(item, array, i));
                } else if (item.startsWith("-U")) {
                    server.setUrl(getConfigString(item, array, i));
                } else if (item.startsWith("-h")) {
                    server.setIp(getConfigString(item, array, i));
                } else if (item.startsWith("-i")) {
                    server.setId(getConfigString(item, array, i));
                } else if (i == 0) {
                    server.setIp(item);
                }
                i++;
            }
            String _url = server.getUrl();
            server.setUrl(_url.replace("${host}", server.getIp()).replace("${port}", server.getPort()));
        }

        public static String getConfigString(String item, String[] array, int i) {
            return (item.length() == 2 ? array[i + 1] : item.substring(2)).trim();
        }

    }

}

 //数据源配置

package com.hengyu.ticket.common;

import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lgf on 2016/4/3.
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    private static Map<Object, Object> targetDataSources = new HashMap<>();

    //初始化数据源
    public static void initDataSource(){
        try {
            List<CommonLoadBalancing.Server> servers = CommonLoadBalancing.getServers() ;
            for (CommonLoadBalancing.Server server:servers){
                DriverManagerDataSource ds = new DriverManagerDataSource();
                ds.setUsername(server.getUsername());
                ds.setPassword(server.getPassword());
                ds.setDriverClassName(CommonLoadBalancing.DB_DRIVER);
                ds.setUrl(server.getUrl());
                targetDataSources.put(String.valueOf(server.getId()),ds);
            }
        }catch (Exception e){
                e.printStackTrace();
        }
    }

    static {
        initDataSource();
    }

    public DynamicDataSource() throws IOException {
        super.setTargetDataSources(targetDataSources);
    }

    @Override
    protected Object determineCurrentLookupKey() {
        CommonLoadBalancing.Server server = CommonLoadBalancing.getServer();
        System.out.println("=====>>获取数据源:" +server);
        return server.getIndex().toString();
    }

    public Map<Object, Object> getTargetDataSources() {
        return targetDataSources;
    }

    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        this.targetDataSources = targetDataSources;
    }

}

 //spring配置

 

package com.hengyu.ticket.common;

import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.web.filter.OncePerRequestFilter;

import java.lang.reflect.Method;

/**
 * Created by lgf on 2016/4/4.
 */
public class MethodInterceptor implements org.aopalliance.intercept.MethodInterceptor {

    @Autowired
    private TransactionInterceptor transactionInterceptor;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Class targetClass = invocation.getThis() != null? AopUtils.getTargetClass(invocation.getThis()):null;
        final TransactionAttribute txAttr = transactionInterceptor.getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
        System.out.println("*******"+txAttr.isReadOnly());
        CommonLoadBalancing.setServerType(txAttr.isReadOnly());
        Object proceed = invocation.proceed();
        return proceed;
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
             	 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
			     http://www.springframework.org/schema/mvc 
			     http://www.springframework.org/schema/mvc/spring-mvc.xsd
	             http://www.springframework.org/schema/context
	             http://www.springframework.org/schema/context/spring-context-3.2.xsd
	             http://www.springframework.org/schema/aop
	             http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
	             http://www.springframework.org/schema/tx
	             http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<!-- 支持注解 -->
	<mvc:annotation-driven />

	<!-- 扫描控制器类 -->
	<context:component-scan base-package="com.hengyu.ticket.service" />

	<!-- 加载配置文件 -->
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:config.properties</value>
			</list>
		</property>
	</bean>

	<bean id="dynamicDataSource" class="com.hengyu.ticket.common.DynamicDataSource">
	</bean>


	<!--  配置 sqlSessionFactory -->
	<bean id="sqlSessionFactory" name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dynamicDataSource"/>
		<property name="plugins">
			<array>
				<bean class="com.hengyu.ticket.common.SqlIntercept">
					<property name="show_sql" value="false"></property>
				</bean>
			</array>
		</property>
		<property name="configurationProperties">
			<props>
<!-- 				<prop key="cacheEnabled">true</prop> -->
			</props>
		</property>
		<property name="mapperLocations" value="com.hengyu.ticket.dao.*.xml"/>
		<property name="typeAliasesPackage" value="com.hengyu.ticket.entity"/>
	</bean>

	<!-- 配置 mapperScannerConfigurer 扫描配置文件 -->
	<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
		<property name="basePackage" value="com.hengyu.ticket.dao"/>
<!-- 		<property name="sqlSessionTemplateBeanName" value="SqlSessionTemplate"/> -->
	</bean>

	<!-- 事务管理器 -->
	<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dynamicDataSource"></property>
	</bean>

	<!-- 事物切面 -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes >
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="load*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>


	<aop:config>
		<aop:advisor pointcut="execution(* com.hengyu.ticket.service.*.*(..))"
			advice-ref="txAdvice"/>
		<aop:advisor pointcut="execution(* com.hengyu.ticket.service.*.*(..))"
			advice-ref="methodInterceptor" order="1"/>
		<aop:aspect id="im" ref="methodInterceptor">
			<aop:pointcut id="mi" expression="execution(* com.hengyu.ticket.service.*.*(..))"></aop:pointcut>
		</aop:aspect>
	</aop:config>

	<bean id="methodInterceptor" class="com.hengyu.ticket.common.MethodInterceptor"></bean>
</beans>

 //数据库配置SERVER.JSON

 

{
  "username": "root",
  "password": "admin",
  "port": "3306",
  "driver": "com.mysql.jdbc.Driver",
  "url": "jdbc:mysql://${host}:${port}/ticket?characterEncoding=utf8",
  "master": [
    "127.0.0.1"
  ],
  "slave": [
    "localhost"
  ]
}

 

分享到:
评论

相关推荐

    完美解决多应用服务器负载均衡环境下spring quartz同一定时任务重复执行问题

    在多应用服务器负载均衡环境下,Spring Quartz定时任务的重复执行问题是一个常见的挑战。Spring Quartz是一个强大的、开源的作业调度框架,允许开发者定义和执行复杂的定时任务。然而,当多个服务器实例并行运行时,...

    初学SpringCloud连接Oracle数据库

    Ribbon是客户端负载均衡器,Feign是一个声明式HTTP客户端。配置它们可以使你的服务通过服务名而不是IP地址来调用其他服务,从而实现服务间的通信。 例如,为Ribbon配置一个配置类: ```java @Configuration public...

    Springcloud 多数库 多数据源整合,查询动态切换数据库

    4. **Ribbon和Feign客户端**:在Spring Cloud中,Ribbon和Feign常用于服务间的负载均衡。如果各个服务连接不同的数据源,我们可以通过配置Ribbon或Feign客户端,使它们根据请求参数或特定规则选择合适的数据源。 5....

    CAS JPA-Ticket存储解决负载均衡配置

    通过调整和优化相关的Spring配置,可以确保在不同服务器之间实现会话的一致性和系统的高可用性。需要注意的是,实际部署时应根据具体的硬件资源、网络环境以及安全性需求进行细致的调整和测试,以达到最佳效果。

    Nginx+tomcat 实现负载均衡session共享demo

    配置`Nginx`进行负载均衡的步骤如下: 1. 安装`Nginx`:在服务器上安装`Nginx`,确保它能够正常启动和运行。 2. 配置`Nginx`:在`nginx.conf`配置文件中,我们需要定义一个upstream块,列出所有`Tomcat`服务器的IP...

    springcloud集成flowable6.5.0适配达梦数据库的模块

    2. 路由与负载均衡:使用Zuul或Spring Cloud Gateway作为API网关,实现请求的路由和负载均衡。 3. 配置管理:利用Spring Cloud Config服务器集中管理所有微服务的配置,方便统一更新。 4. 安全认证:集成Spring ...

    springboot-nginx-redis-session共享、TCPUDP负载均衡.zip

    本资料包“springboot-nginx-redis-session共享、TCPUDP负载均衡.zip”提供了一套完整的解决方案,涉及到Spring Boot、Nginx、Redis以及TCP/UDP负载均衡的整合。下面将详细解释这些技术及其在实际应用中的作用。 ...

    HibernateSpring多数据库解决方案.doc

    在互联网行业中,数据库管理是关键的一环,尤其是在大型系统中,常常需要处理多个数据库以实现负载均衡、数据冗余或不同的访问策略。本方案主要探讨如何在基于Hibernate和Spring框架的环境中实现多数据库的管理,...

    nginx+tomcat+redis负载均衡所需jar及nginx、redis文件及说明文档

    6. 测试配置,确保所有组件都能正常工作,并根据需求调整负载均衡策略。 在实际部署中,你可能还需要考虑其他的优化措施,如使用SSL加密通信、设置健康检查机制以检测后端服务器状态、调整`Nginx`和`Redis`的缓存...

    spring-数据库元

    通过上述分析,我们可以看到Spring框架下多数据源配置及动态数据源切换的实现并不复杂,但在实际应用中还需要注意一些细节问题,比如事务的一致性管理、数据源的负载均衡等。此外,随着技术的发展,未来还可能出现更...

    基于SpringCloud的Idea集成Ribbon客户端负载均衡设计源码

    该项目是一款基于SpringCloud框架的Idea集成Ribbon客户端负载均衡设计源码,总文件量达86个,涵盖33个Java源文件、12个XML配置文件、6个HTML文件、5个Git忽略文件、4个数据库文件、4个JAR包、4个属性文件、4个YAML...

    Nginx+Tomcat+Redis实现负载均衡过程中session所需架包

    在构建高性能、高可用性的Web应用...这个过程中涉及的关键技术包括Nginx的反向代理和负载均衡配置、Tomcat的session管理、以及Redis的分布式数据存储。正确配置和优化这些组件,将有助于构建一个健壮的分布式Web系统。

    java配置多数据库

    在实际的应用场景中,可能还需要考虑事务管理、异常处理以及读写分离、负载均衡等高级特性。例如,可以使用Spring的PlatformTransactionManager来管理跨数据库的事务,或者利用AOP(面向切面编程)来实现特定的策略...

    springaop多数据库读写分离

    在IT行业中,数据库读写分离是一种常见的优化策略,主要用于提高系统的并发处理能力和数据读取...在实际项目中,还可以考虑使用中间件如MySQL的Proxy或商业化解决方案如MaxScale来实现更高级的读写分离和负载均衡策略。

    springcloud数据库原理课程思政网站论文.doc

    使用Java编程语言和SpringBoot框架开发各服务,集成SpringCloud组件,实现服务注册与发现、负载均衡等功能。利用MyBatis作为持久层框架,操作MySQL数据库。系统完成后,进行全面的功能测试、性能测试和安全测试,...

    spring cloud微服务框架demo完整可用2版(注册中心+生产者+消费者+feign负载均衡+hystrix断路器+仪表盘+gate路由网关+配置中心)

    spring cloud微服务框架demo完整可用2版 比第一版多集成了mybatis...(注册中心+生产者+消费者+feign负载均衡+hystrix断路器+仪表盘+gate路由网关+config配置中心+mybatis+oracle+mybatisPlus generator代码自动生成)

    Spring 配置各种数据源

    以下将详细阐述Spring配置各种数据源的方法、原理以及优缺点。 1. **单数据源配置** 单一数据源是最常见的配置,适用于大多数简单应用。在Spring Boot中,可以通过`application.properties`或`application.yml`...

    Nginx负载均衡条件下Redis共享Session测试

    Nginx的负载均衡功能可以通过配置upstream模块实现。它可以根据不同的策略(如轮询、最少连接、IP哈希等)将请求分发到后端服务器集群,提高服务的并发处理能力。在多服务器环境中,确保用户在切换服务器时仍能访问...

    Spring多数据源配置

    Spring框架提供了灵活且强大的机制来处理这种场景,使得开发者能够在一个应用中集成多个数据源,从而实现数据的分区存储、读写分离、负载均衡等策略。本文将详细探讨如何在Spring环境中配置多个数据源,包括...

    nginx-tomcat-redis负载均衡,session共享依赖jar包

    在配置`nginx`进行负载均衡时,通常会使用轮询、权重轮询、最少连接数等策略。例如,一个简单的`nginx`负载均衡配置示例: ```nginx http { upstream backend { server backend1.example.com; server backend2....

Global site tag (gtag.js) - Google Analytics