Dubbo+zookeeper+smm+业务与服务分离+MySQL集群(读写分离)

本文介绍了一种基于Docker容器的高性能架构设计方案,通过负载均衡、读写分离、微服务和分布式缓存等技术,实现了高并发场景下的系统稳定性和响应速度提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:

         随着企业的发展,用户访问量迅猛增加,业务类型和业务量增加。企业对整个应用系统提出高性能,高可用,高吞吐量,7*24小时等等。然而企业(公司)的单台数据库无法响应用户请求,用户量对响应速度提出更高的要求,开发代码管理不当,开发效率低,业务逻辑混乱。为了解决以上问题,本文提出一种以Docker容器为基础的高性能架构。主要使用一个容器安装nginx做负载均衡,使用6个容器安装tomcat将业务代码和服务代码分开部署,其中3个tomcat部署业务代码,3个tomcat部署服务代码。业务层通过阿里开源框架Dubbo框架实现远程调用服务层。使用3个容器部署zookeeper做Dubbo资源管理。使用4个容器部署MySQL集群实现数据库读写分离,其中1个master,3个slave。关于数据库的负载均衡本文引用基于uid 哈希算法。本文最后给出实验结构表明该架构具有高响应性,负载均衡性,可用性。

 

一、架构部署

     本架构分为五层,如上图所示应用层主要开发(android,IOS,web,微信小程序,H5,支付宝等等),分发层除了做负载均衡也可以做防DDoS,防SQL注入,WAF等小型安全应用。业务主要做业务逻辑开发,当然也可以通过AOP做系统日志,权限控制等等,除此之外,可以使用redis集群做session共享和缓存加速(某些业务可以放到redis来做,减少数据库压力)。服务层主要做DAO服务或者其他算法服务。zookeeper主要做资源管理。Dubbo管理员可以查看业务层和服务层的一些情况(有点类型小型微型数据治理的概念)。

二、实现如下:(说明,因为本文测试花了两天时间,可能下面展示的有些IP地址与架构中所展示的对不上,但是步骤没问题)

1、创建master数据库

      1.1、创建 master.cnf

# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL Community Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
explicit_defaults_for_timestamp

log-bin = mysql-bin 
server-id = 1 

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address   = 127.0.0.1

#log-error  = /var/log/mysql/error.log

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/

 1.2、创建 sources.list

deb http://mirrors.aliyun.com/debian wheezy main contrib non-free
deb-src http://mirrors.aliyun.com/debian wheezy main contrib non-free
deb http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free
deb-src http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free
deb http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free
deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free

1.3、创建容器

docker run -d -e MYSQL_ROOT_PASSWORD=123qwe --name mysql_master -v D:/VMdata/mysql/master/master.cnf:/etc/mysql/my.cnf  -v D:/VMdata/mysql/master/sources.list:/etc/apt/sources.list   -p 33006:3306 mysql:5.7

1.4、找到局域网IP

>>apt-get update -y
>>apt install net-tools
>>ifconfig

eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0

 

 1. 5、进入终端

>>docker exec -it mysql_master bash
>>mysql -uroot -p
>>grant replication slave on *.* to 'slave01'@'%' identified by 'slave01';
>>flush privileges;
>>show master status;

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      592 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

2、创建slave01数据库(其他照猫画虎)

   2.1、创建 slave01.cnf, 将server-id = 1 修改为server-id = 2(每个slave都不一样就是)

   2.2、创建容器

docker run -d -e MYSQL_ROOT_PASSWORD=123qwe --name mysql_slave01 -v D:/VMdata/mysql/slaves/u01/slave01.cnf:/etc/mysql/my.cnf  -v D:/VMdata/mysql/slaves/u01/sources.list:/etc/apt/sources.list   -p 33008:3306 mysql:5.7

  2.3、进入终端

mysql> change master to master_host='172.17.0.2',
    master_user='slave01',
    master_password='slave01',
    master_log_file='mysql-bin.000003',
    master_log_pos=0,        
    master_port=3306;
mysql> start slave;
mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: slave01
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1326
               Relay_Log_File: 1d464b6d48fd-relay-bin.000002
                Relay_Log_Pos: 1539
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1326
              Relay_Log_Space: 1753
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 408a8322-f9cd-11e8-a764-0242ac110002
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

3、在master创建数据库、创建表并添加数据,查看是否已经同步到slaves

mysql> create database xiaochongdian;
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| xiaochongdian      |
+--------------------+
5 rows in set (0.00 sec)

mysql> use xiaochongdian
Database changed
mysql> insert into user values(1,'xm01','112233tt'),(2,'xw02','eerr4433'),(2,'xr03','rreeww');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from user;
+------+------+----------+
| id   | name | pwd      |
+------+------+----------+
|    1 | xm01 | 112233tt |
|    2 | xw02 | eerr4433 |
|    2 | xr03 | rreeww   |
+------+------+----------+
3 rows in set (0.01 sec)

4、进入slave01终端查看(其他数据库效果一样)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| xiaochongdian      |
+--------------------+
5 rows in set (0.00 sec)

mysql> use xiaochongdian
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from user;
+------+------+----------+
| id   | name | pwd      |
+------+------+----------+
|    1 | xm01 | 112233tt |
|    2 | xw02 | eerr4433 |
|    2 | xr03 | rreeww   |
+------+------+----------+
3 rows in set (0.00 sec)

到这里已经实现master-slaves同步了,只有在master中写slaves才能看到,要是在slave01中写,其他数据库是看不到的,所以

很明显,读写分离就只能master是写,slaves读。

5、部署zookeeper集群(我们采用三台机器)

version: '2'
services:
    my_zk1:
        image: zookeeper
        restart: always
        container_name: my_zk1
        ports:
            - "2181:2181"
        environment:
            ZOO_MY_ID: 1
            ZOO_SERVERS: server.1=my_zk1:2888:3888 server.2=my_zk2:2888:3888 server.3=my_zk3:2888:3888

    my_zk2:
        image: zookeeper
        restart: always
        container_name: my_zk2
        ports:
            - "2182:2181"
        environment:
            ZOO_MY_ID: 2
            ZOO_SERVERS: server.1=my_zk1:2888:3888 server.2=my_zk2:2888:3888 server.3=my_zk3:2888:3888

    my_zk3:
        image: zookeeper
        restart: always
        container_name: my_zk3
        ports:
            - "2183:2181"
        environment:
            ZOO_MY_ID: 3
            ZOO_SERVERS: server.1=my_zk1:2888:3888 server.2=my_zk2:2888:3888 server.3=my_zk3:2888:3888

分别进去看看哪个是leader

     5.1  进入my_zk1

>>D:\VMdata\zookeeper>docker exec -it 4dab1b3d59a1 /bin/bash
>>cd bin
>>./zkServer.sh status

ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: follower  #没被选上

  5.2  进入my_zk2

>>docker exec -it ecb7befbf3e0 /bin/bash
>>cd bin
>>./zkServer.sh status


ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: leader    #哈哈哈找到了

  5.3 进入my_zk3

>>docker exec -it e4da8424ab59 /bin/bash
>> cd bin
>>./zkServer.sh status

ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Mode: follower  #没被选上

6、创建tomcat、redis、nginx在本博客的另一篇文章中由详细的步骤,这里不再做啰嗦。

7、创建业务层代码,项目的目录结构如下图,对着抄没毛病。我们从下图看到业务层根本不需要程序员知道接口是怎么实现的,尽管做业务逻辑就可以(一本正经的螺丝钉就怪架构师,哈哈)。因为我们将代码部署在3台机器上,按道理只要写好一份copy上去就行,但是这里为了实验效果,需要稍微改一下在部署,该的地方你往下,我不上你也懂。(默认你懂)

   

    7.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>xcdweb</groupId>
  <artifactId>xcdweb</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>xcdweb Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.session</groupId>
      <artifactId>spring-session-data-redis</artifactId>
      <version>1.2.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.8.1</version>
    </dependency>
    <!-- 3.Servlet web -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.5.4</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- 4.Spring -->
    <!-- 1)Spring核心 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- 2)Spring DAO层 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- 3)Spring web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- Dubbo 依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.5.7</version>
      <exclusions>
        <exclusion>
          <artifactId>spring</artifactId>
          <groupId>org.springframework</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <!-- Zookeeper 依赖 -->
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.5.3-beta</version>
      <exclusions>
        <exclusion>
          <artifactId>log4j</artifactId>
          <groupId>log4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.101tec</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.8</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>xcdweb</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

 7.2 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="spring-*"/>
</beans>

7.3 spring-dubbo-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <dubbo:application name="xcd-consumer" />
    <dubbo:registry   protocol="zookeeper" address="172.17.0.2:2181,172.17.0.3:2181,172.17.0.4:2181"/>
    <dubbo:protocol name="dubbo" port="20882" />
    <dubbo:provider timeout="1500000" retries="0" delay="-1"/>
    <dubbo:consumer check="false" timeout="1500000"/>
</beans>

 7.4 spring-dubbo-consumer.xml

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="userService" interface="com.service.UserService" />
</beans>

 7.5 spring-springSession-redis.xml

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="example"/>
    <bean id="redisHttpSessionConfiguration"
          class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="600"/>
    </bean>
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大空闲数 -->
        <property name="maxIdle" value="300" />
        <!-- 最大连接数 -->
        <property name="maxTotal" value="100" />
        <!-- 最大等待时间 -->
        <property name="maxWaitMillis" value="20000" />
    </bean>
    <bean id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
        <property name="hostName" value="172.17.0.5"/>
        <property name="port" value="6379"/>
        <property name="timeout" value="3000"/>
        <property name="usePool" value="true"/>
        <property name="poolConfig" ref="jedisPoolConfig"/>
    </bean>
</beans>

7.6 spring-web.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <mvc:annotation-driven />
    <mvc:default-servlet-handler/>
    <!-- 3.配置jsp 显示ViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <!-- 4.扫描web相关的bean -->
    <context:component-scan base-package="com" />
</beans>

  7.7 web.xml

 

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1" metadata-complete="true">
    <!-- 配置DispatcherServlet -->
    <servlet>
        <servlet-name>xcddispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置springMVC需要加载的配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/applicationContext.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>xcddispatcher</servlet-name>
        <!-- 默认匹配所有的请求 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 使用 spring框架自己提供的过滤器解决乱码 -->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

7.8 indes.jsp(为了显示效果,本文部署3份代码在业务层,知识加了不同的输出)


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2 style="color: red">tomcat3提供本页面</h2>
<h2>Hello World!   测试入口:注册和登陆--两个功能实现数据读写分离验证</h2>
<h2>Hello World!   测试入口:验证业务层高可用</h2>
<h2>Hello World!   测试入口:验证服务层高可用</h2>
<h2>Hello World!   测试入口:验证session一致性</h2>
<h2><a href="zhuce.do">注册</a></h2>
<h2><a href="denglu.do">登陆</a></h2>
</body>
</html>

7.9 具体的JSP代码比较简单,在实验结果中就可以反推代码怎么写的

8、服务层的实现如下。先看下图项目结构。是在Eclipse中写的,可能某些人看不习惯这个白色的,下图中有些x,不要管,没有bug,这是Eclipse这个编译器的痛。我们看到这里就是接口具体实现和算法实现的地方。

 

  8.1还是先从配置入手 pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>xcdServer</groupId>
  <artifactId>xcdServer</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>xcdServer Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>

    <!-- 单元测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>
    <!-- 1.日志 -->
    <!-- 实现slf4j接口并整合 -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.1</version>
    </dependency>
    <!-- 2.数据库 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.37</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <!-- DAO: MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!-- 3.Servlet web -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.5.4</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- 4.Spring -->
    <!-- 1)Spring核心 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- 2)Spring DAO层 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- 3)Spring web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- Dubbo 依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.5.7</version>
      <exclusions>
        <exclusion>
          <artifactId>spring</artifactId>
          <groupId>org.springframework</groupId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- Zookeeper 依赖 -->
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.5.3-beta</version>
      <exclusions>
        <exclusion>
          <artifactId>log4j</artifactId>
          <groupId>log4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.101tec</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.8</version>
    </dependency>





    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>xcdServer</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

8.2 UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.UserDao">
    <!-- 目的:为dao接口方法提供sql语句配置 -->
    <select id="readpwdByName" resultType="String" parameterType="String">
        SELECT pwd FROM user  WHERE  name = #{name}
    </select>
    <insert id="write" parameterType="String">
     insert into user (name,pwd) values (#{name},#{pwd})
  </insert>
</mapper>

8.3  applicationContext.xml 和业务层一样

8.4 jdbc.properties 

#master
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://172.17.0.9:3306/xiaochongdian?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123qwe
jdbc.initialSize=1
jdbc.minIdle=1
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=180
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.validationQuery=SELECT 1
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false
#slave01
slave01.driver=com.mysql.jdbc.Driver
slave01.url=jdbc:mysql://172.17.0.6:3306/xiaochongdian?useUnicode=true&characterEncoding=utf-8&useSSL=false
slave01.username=root
slave01.password=123qwe
slave01.initialSize=1
slave01.minIdle=1
slave01.maxActive=20
slave01.maxWait=60000
slave01.removeAbandoned=true
slave01.removeAbandonedTimeout=180
slave01.timeBetweenEvictionRunsMillis=60000
slave01.minEvictableIdleTimeMillis=300000
slave01.validationQuery=SELECT 1
slave01.testWhileIdle=true
slave01.testOnBorrow=false
slave01.testOnReturn=false
#slave02
slave02.driver=com.mysql.jdbc.Driver
slave02.url=jdbc:mysql://172.17.0.7:3306/xiaochongdian?useUnicode=true&characterEncoding=utf-8&useSSL=false
slave02.username=root
slave02.password=123qwe
#slave03
slave03.driver=com.mysql.jdbc.Driver
slave03.url=jdbc:mysql://172.17.0.8:3306/xiaochongdian?useUnicode=true&characterEncoding=utf-8&useSSL=false
slave03.username=root
slave03.password=123qwe

8.5 spring-dao.xml

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置整合mybatis过程 -->
    <!-- 1.配置数据库相关参数properties的属性:${url} -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!-- 2.数据库连接池 -->
    <bean id="masterWriteSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    <bean id="slave01ReadSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${slave01.driver}" />
        <property name="jdbcUrl" value="${slave01.url}" />
        <property name="user" value="${slave01.username}" />
        <property name="password" value="${slave01.password}" />
    </bean>
    <bean id="slave02ReadSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- 配置连接池属性 -->
        <property name="driverClass" value="${slave02.driver}" />
        <property name="jdbcUrl" value="${slave02.url}" />
        <property name="user" value="${slave02.username}" />
        <property name="password" value="${slave02.password}" />
    </bean>
    <bean id="slave03ReadSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- 配置连接池属性 -->
        <property name="driverClass" value="${slave03.driver}" />
        <property name="jdbcUrl" value="${slave03.url}" />
        <property name="user" value="${slave03.username}" />
        <property name="password" value="${slave03.password}" />
    </bean>

     <bean id="dataSource" class="com.spring.util.dynamicDataSource.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="write"  value-ref="masterWriteSource" />
                <entry key="read01"  value-ref="slave01ReadSource" />
                <entry key="read02"  value-ref="slave02ReadSource" />
                <entry key="read03"  value-ref="slave03ReadSource" />
            </map>
        </property>
		  <property name="defaultTargetDataSource"  ref="masterWriteSource"  /> 
    </bean>
    <!-- 3.配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 别名 -->
        <property name="typeAliasesPackage" value="com.bean"></property>
        <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
        <!--<property name="configLocation" value="classpath:mybatis-config.xml" />-->
        <!-- 扫描sql配置文件:mapper需要的xml文件 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml" />
    </bean>
    <!-- 4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <!-- 给出需要扫描Dao接口包 -->
        <property name="basePackage" value="com.dao" />
    </bean>
</beans>

8.6 spring-dubbo-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <dubbo:application name="xcd-service" logger="slf4j"/>
    <dubbo:registry   protocol="zookeeper" address="172.17.0.2:2181,172.17.0.3:2181,172.17.0.4:2181"/>
    <dubbo:protocol name="dubbo" port="20882" />
    <dubbo:provider timeout="12000000" retries="0" delay="-1"/>
    <dubbo:consumer check="false" timeout="12000000"/>
</beans>

8.7 spring-dubbo-provider.xml

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <dubbo:service interface="com.service.UserService" ref="userService"  timeout="1000000"/>
    <!-- 和本地bean一样实现服务 -->
    <bean id="userService" class="com.serviceImpl.UserServiceImpl" />
</beans>

8.8 spring-service.xml

<?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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 扫描service包下所有使用注解的类型 -->
    <context:component-scan base-package="com" />
    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 配置基于注解的声明式事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

8.9 spring-web.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <!-- 配置SpringMVC -->
    <!-- 1.开启SpringMVC注解模式 -->
    <!-- 简化配置:
        (1)自动注册DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter
        (2)提供一些列:数据绑定,数字和日期的format @NumberFormat, @DateTimeFormat, xml,json默认读写支持
    -->
    <mvc:annotation-driven />

    <!-- 2.静态资源默认servlet配置
        (1)加入对静态资源的处理:js,gif,png
        (2)允许使用"/"做整体映射
     -->
    <mvc:default-servlet-handler/>

    <!-- 3.配置jsp 显示ViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 4.扫描web相关的bean -->
    <context:component-scan base-package="com" />
</beans>

8.10 mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置全局属性 -->
    <settings>
        <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
        <setting name="useGeneratedKeys" value="true" />

        <!-- 使用列别名替换列名 默认:true -->
        <setting name="useColumnLabel" value="true" />

        <!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

8.11 User 实体geter,seter自己写

private String name;
private String pwd;

8.12 UserDao

package com.dao;
public interface UserDao {
    public void  write(String name,String pwd);
    public String readpwdByName(String name);
}

8.13 UserService

package com.service;

public interface UserService {
    public void  write(String name,String pwd);
    public String readpwdByName(String name);
    public String writeandreturn(String name,String pwd);
}

8.14 UserServiceImpl  (部署在不同的tomcat中自己改一下编号,演示用的,读的负载字在这里实现,简单的hash,挂了下一个)

package com.serviceImpl;

import com.dao.UserDao;
import com.service.UserService;
import com.spring.util.dynamicDataSource.DataSource;

import org.springframework.beans.factory.annotation.Autowired;

public class UserServiceImpl  implements UserService {

    @Autowired
    UserDao userDao;


    @Override
    public void write(String name,String pwd){
    	userDao.write(name, pwd);
    }

    @DataSource("write")
    public String writeandreturn(String name,String pwd) {
    	write(name,pwd);
    	return "写操作: 路由:MySQL_master->服务层tomcat4->";
    }
    @DataSource("read01")
    public String readpwdByName01(String name) {
    	String msg="读取结果:"+userDao.readpwdByName(name)+"\n 路由:MySQL_slave01->服务层tomcat6->";
        return msg;
    }
    @DataSource("read02")
    public String readpwdByName02(String name) {
    	String msg="读取结果:"+userDao.readpwdByName(name)+"\n路由:MySQL_slave02->服务层tomcat6->";
        return msg;
    }
    @DataSource("read03")
    public String readpwdByName03(String name) {
    	String msg="读取结果:"+userDao.readpwdByName(name)+"\n 路由:MySQL_slave03->服务层tomcat6->";
        return msg;
    }
    
    @Override
    public String readpwdByName(String name){
    	String msg=null;
    	int slaveID=Math.abs(name.hashCode())%3;//配置省略
    	System.out.println("ID:============================》"+slaveID);
    	switch (slaveID) {
		case 0:
			msg=readpwdByName01(name);
			if( msg!=null) {
				break;
			}
		case 1:
			msg=readpwdByName02(name);		
			if( msg!=null) {
				break;
			}
		case 2:
			msg=readpwdByName03(name);
			if( msg!=null) {
				break;
			}
		default:
			msg=readpwdByName01(name);
			if( msg!=null) {
				break;
			}
			msg=readpwdByName02(name);		
			if( msg!=null) {
				break;
			}
			msg=readpwdByName03(name);
			if( msg!=null) {
				break;
			}
			
		}
    	
        return msg;
    }
}

8.15 下面是多数据源读写实现,这个就不贴出来了比较简单

 

三、测试结果

1、docker

   2数据库集群

 3、Dubbo管理(挂了一个照样用不误)

4、访问结果

 

 

 

总结与展望:

1、本文使用docker容器实现架构部署,但是在具体应用时,因各个企业拥有的设备数量以及设备配置不一样,部署时应加以考虑。

2、测试使用的框架为ssm+duboo+zookeeper+springsession,duboo框架在这里的具体担任远程调用角色,有多种其他实现。

3、本文没有实现redis缓存加速,下期在写

4、当数据量增大的时候,boss准备搞机器学习深度学习什么人工智能,想搞BI,就离不开大数据架构部署,如何将大数据平台接上去,下下期见。

5、有了机器学习,boss既然就想到实时地把机器学习,深度学习的应用成果上线,如何上线?引出实时处理,--->kafka(MQ)、flume等等隆重登场

6、讲了这么多,就一点:数据--->传输---->处理--->传输---->数据

 

 

好了,牛B就吹到这,哈哈哈!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值