111-MyCat

1. 创建ego-order-web订单系统

(1) 描述订单系统的实现流程

进行 spring 配置:

applicationContext-dao.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

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

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.bjsxt.ego.order.dao.impl" />

</beans>

applicationContext-dubbo.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

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

http://code.alibabatech.com/schema/dubbo

http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 添加服务消费者的标志 -->

<dubbo:application name="ego-order-web-consumer"/>

<!-- 指定注册中心 -->

<dubbo:registry address="192.168.224.129:2181,192.168.224.129:2182,192.168.224.129:2183" protocol="zookeeper" />

<!-- spring容器中存在一个远程服务的代理对象 -->

<dubbo:reference interface="com.bjsxt.ego.rpc.service.TbOrderService" id="tbOrderServiceProxy"></dubbo:reference>

</beans>

applicationContext-redis.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

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

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

">

<!-- 加载cache.properties-->

<!-- <context:property-placeholder location="classpath:cache.properties"/> -->

<!-- 实例化JedisCluster -->

<bean id="cluster" class="redis.clients.jedis.JedisCluster">

<constructor-arg name="nodes">

<set>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6380"></constructor-arg>

</bean>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6381"></constructor-arg>

</bean>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6382"></constructor-arg>

</bean>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6383"></constructor-arg>

</bean>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6384"></constructor-arg>

</bean>

<bean class="redis.clients.jedis.HostAndPort">

<constructor-arg name="host" value="192.168.224.129"></constructor-arg>

<constructor-arg name="port" value="6385"></constructor-arg>

</bean>

</set>

</constructor-arg>

</bean>

</beans>

applicationContext-service.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

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

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.bjsxt.ego.order.service.impl" />

</beans>

springmvc.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

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

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.xsd">

<!-- 扫描controller -->

<context:component-scan base-package="com.bjsxt.ego.order.controller" />

<!-- mvc:annotation-driven -->

<mvc:annotation-driven ></mvc:annotation-driven>

<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>

<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>

<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>

<!-- 视图解析器 -->

<bean id="viewResovler"

class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!-- 表示使用的视图技术是jsp -->

<property name="viewClass"

value="org.springframework.web.servlet.view.JstlView"></property>

<!-- 前缀 -->

<property name="prefix" value="/WEB-INF/jsp/"></property>

<!-- 后缀 -->

<property name="suffix" value=".jsp"></property>

</bean>

<!-- 实例化拦截器对象 -->

<bean id="loginInterceptor" class="com.bjsxt.ego.order.interceptor.LoginInterceptor"></bean>

<!-- 注册拦截器 -->

<mvc:interceptors>

<mvc:interceptor>

<mvc:mapping path="/**"/>

<ref bean="loginInterceptor"/>

</mvc:interceptor>

</mvc:interceptors>

</beans>

配置 web.xml:

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

<display-name>ego-order-web</display-name>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<!--

<servlet-mapping>

<servlet-name>default</servlet-name>

<url-pattern>/favicon.ico</url-pattern>

</servlet-mapping> -->

<!-- 以监听器的方式启动spring容器 -->

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!-- 指定spring的配置文件 -->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:spring/applicationContext-*.xml</param-value>

</context-param>

<!-- POST请求的乱码过滤器 -->

<filter>

<filter-name>encodingFilter</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 -->

<filter-mapping>

<filter-name>encodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- springmvc的servlet -->

<servlet>

<servlet-name>ego-order-web</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- 指定springmvc的配置文件 -->

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:spring/springmvc.xml</param-value>

</init-param>

<!-- 让springmvc随系统启动而启动 -->

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>ego-order-web</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>

4 建立 PageController:

@RequestMapping("/{url}")

public String loadPage(@PathVariable String url) {

return url;

}

(2) 描述订单系统中需要的表和表之间的关系

订单表、订单明细表(一对多)

用户表、订单表(一对多)

2. ego-order-web添加拦截器

(1) 说明springmvc中拦截器postHandle()方法的执行时间和作用

3. 保存订单信息_查看订单列表_明细

(1) 描述用户订单保存中订单明细表中的数据是怎么获取的?

发布信息:

//完成订单信息保存

public void saveTbOrderService(TbOrder tbOrder,List<TbOrderItem> orderItems,TbOrderShipping tbOrderShipping );

//完成订单信息保存

@Override

public void saveTbOrderService(TbOrder tbOrder, List<TbOrderItem> orderItems, TbOrderShipping tbOrderShipping) {

try {

tbOrderMapper.insert(tbOrder);

for(TbOrderItem orderItem:orderItems) {

tbOrderItemMapper.insert(orderItem);

}

tbOrderShippingMapper.insert(tbOrderShipping);

} catch (Exception e) {

e.printStackTrace();

}

}

消费信息:

//完成用户下订单

public Map<String, String> saveOrderService(TbOrder tbOrder,Long uid,TbOrderShipping orderShipping);

//完成用户下订单

@Override

public Map<String, String> saveOrderService(TbOrder tbOrder, Long uid, TbOrderShipping orderShipping) {

try {

Date date = new Date();

//产生订单号

String orderid = String.valueOf(IDUtils.genItemId());

tbOrder.setOrderId(orderid);

tbOrder.setPostFee("123");

tbOrder.setStatus(2);

tbOrder.setCreateTime(date);

tbOrder.setUpdateTime(date);

tbOrder.setPaymentTime(date);

tbOrder.setConsignTime(date);

tbOrder.setEndTime(date);

tbOrder.setCloseTime(date);

tbOrder.setShippingName("EMS");

tbOrder.setShippingCode("11111");

tbOrder.setUserId(uid);

tbOrder.setBuyerMessage("message");

tbOrder.setBuyerNick("9527");

tbOrder.setBuyerRate(0);

//获取用户购物车集合

Map<Long, CarItem> carMap = loadCarItemMapService(uid);

//创建List<TbOrderItem>

List<TbOrderItem> list = new ArrayList<>();

for (CarItem carItem : carMap.values()) {

//产生订单明细主键

String id = String.valueOf(IDUtils.genItemId());

//创建订单,明细对象

TbOrderItem orderItem = new TbOrderItem();

orderItem.setId(id);

orderItem.setOrderId(orderid);

//获取购物车中的商品对象

TbItem item = carItem.getItem();

orderItem.setItemId(String.valueOf(item.getId()));

orderItem.setNum(carItem.getNum());

orderItem.setTitle(item.getTitle());

orderItem.setPrice(item.getPrice());

orderItem.setTotalFee(item.getPrice()*carItem.getNum());

orderItem.setPicPath(item.getImages()[0]);

list.add(orderItem);

}

orderShipping.setOrderId(orderid);

orderShipping.setReceiverPhone("1111");

orderShipping.setCreated(date);

orderShipping.setUpdated(date);

//调用rpc远程服务

tbOrderServiceProxy.saveTbOrderService(tbOrder, list, orderShipping);

Map<String,String> map = new HashMap<>();

map.put("orderid", orderid);

map.put("total", tbOrder.getPayment());

carItemDao.deleteCarItemMap(String.valueOf(uid));

return map;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

//处理保存订单信息的请求

@RequestMapping("/order/save")

public String orderSave(TbOrder tbOrder,TbOrderShipping tbOrderShipping,HttpServletRequest request) {

//获取当前登录用户对象

TbUser user = (TbUser) request.getAttribute("user");

Long id = user.getId();

Map<String, String> map = orderService.saveOrderService(tbOrder, id, tbOrderShipping);

request.setAttribute("itemid", map.get("itemid"));

request.setAttribute("total", map.get("total"));

return "success";

}

4. Nginx介绍_Nginx安装

(1) 描述nginx的在开发中的作用。

Nginx (engine x) 是一个高性能的 HTTP 和反向代理服务,也是一个 IMAP/POP3/SMTP 服务。其特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用 nginx 网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在连接高并发的情况下,Nginx 是 Apache 服务不错的替代品

(2) 谈谈你对反向代理和正向代理的理解

①位置不同

正向代理,架设在客户机和目标主机之间;

反向代理,架设在服务器端;

②代理对象不同

正向代理,代理客户端,服务端不知道实际发起请求的客户端;

反向代理,代理服务端,客户端不知道实际提供服务的服务端;

5. Nginx实现虚拟主机

(1) 谈谈你对nginx虚拟主机的理解

虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟机,每个虚拟主机可以独立对外提供 www 服务,这样就可以实现一台主机对外提供多个web 服务,每个虚拟主机之间是独立的,互不影响的。

虚拟主机技术是互联网服务器采用的节省服务器硬件成本的技术,虚拟主机技术主要应

用于 HTTP(Hypertext Transfer Protocol,超文本传输协议)服务,将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。

(2) nginx实现虚拟主机有几种方式,分别具体描述

基于 IP 的虚拟主机:设置不同的静态IP,保证端口号一致,

基于端口的虚拟主机:设置一个IP,通过不同的端口号访问不同的虚拟主机

基于域名的虚拟主机:端口号一致,通过不同的域名访问不同的虚拟主机

6. Nginx实现反向代理_负载均衡

(1) 描述什么是nginx的反向代理和好处

反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

①保证内网的安全,可以使用反向代理提供 WAF 功能,阻止 web 攻击大型网站,通常将反向代理作为公网访问地址,Web 服务器是内网

②负载均衡,通过反向代理服务器来优化网站的负载

(2) nginx的负载均衡算法有哪些

①轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

②指定权重

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

upstream backserver {

server 192.168.0.14 weight=10;

server 192.168.0.15 weight=10;

}

③IP 绑定 ip_hash

每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

upstream backserver {

ip_hash;

server 192.168.0.14:88;

server 192.168.0.15:80;

}

7. ego-rpc_ego-manager项目发布

(1) 描述ego-rpc项目发布需要什么插件,做哪些配置

需要添加的插件:

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-assembly-plugin</artifactId>

<version>2.5</version>

</plugin>

Pom文件配置:

<resources>

<resource>

<!-- 指定从哪个文件夹拷贝 -->

<directory>src/main/resources/spring</directory>

<!-- 指定将spring配置文件拷贝到jar包中的META-INF/spring目录 -->

<targetPath>META-INF/spring</targetPath>

<includes>

<include>**/*.xml</include>

</includes>

</resource>

<!-- 其他的文件拷贝到默认的位置 -->

<resource>

<!-- 指定从哪个文件夹拷贝 -->

<directory>src/main/resources/mybatis</directory>

<includes>

<include>**/*.xml</include>

</includes>

</resource>

<resource>

<!-- 指定从哪个文件夹拷贝 -->

<directory>src/main/resources/resources</directory>

<includes>

<include>**/*.properties</include>

</includes>

</resource>

<resource>

<!-- 指定从哪个文件夹拷贝 -->

<directory>src/main/resources</directory>

<includes>

<include>**/*.properties</include>

</includes>

</resource>

</resources>

(2) 描述ego-rpc发布为dubbo服务的时候spring配置文件去哪里加载

dubbo加载spring的配置文件的时候,是从META-INF/spring开始查找

8. Mycat介绍_垂直拆分_水平拆分

(1) 谈谈mycat分库垂直拆分的理解。

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分

类,分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库上面

一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一个功

能模块所需要的数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能模块

相互之间的交互点越统一越少,系统的耦合度就越低,系统各个模块的维护性以及扩展性也

就越好。这样的系统,实现数据的垂直切分也就越容易。

(2) 谈谈mycat分库水平拆分的理解。

水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中

9. Mycat相关概念_Mycat安装

(1) 请对mycat以下概念做详细说明

① 数据库中间件

Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。

② 逻辑库(schema)

对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道 数据库的概念,

所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。

③ 逻辑表(table)

分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

④ ER表

关系型数据库是基于实体关系模型(Entity-Relationship Model)之上,通过其描述了真实世界

中事物与关系,Mycat 中的 ER 表即是来源于此。根据这一思路,提出了基于 E-R 关系的

数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父

表,通过表分组(Table Group)保证数据 Join 不会跨库操作。

⑤ 分片规则

前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务

规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将

极大的避免后续数据处理的难度。

10. MyCat配置_数据导入_测试数据拆分

(1) 描述mycat配置的三个关键文件和作用

Schema.xml:配置虚拟库

Server.xml:设置登录名和密码

Rule.xml:设置分片规则

(2) 详细schema.xml常用配置标签和作用

Table:声明虚拟表 name:虚拟表表名dataNode:虚拟表对应的数据分片

rule:分片规则,必须和rile.xml中声明的分片规则的名字一样

ChildeTable:声明er关系表 name:子表的表名 primarKey:指定子表的主键

joinKey:指定子表的外键 parentKey:字表外键

dataNode:声明数据分片 name:分片名称 dataHost:声明分片主机

Database:分片对应的后台物理表

11. Mysql实现主从同步

(1) 谈谈对数据库读写分离的理解

需要搭建主从模式,让主数据库(master)处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库(slave)处理 SELECT 查询操作。

(2) 谈谈对象数据库主从同步的理解

就是一种主备模式的数据库应用.

主库(Master)数据与备库(Slave)数据完全一致.实现数据的多重备份, 保证数据的安全.可以在 Master[InnoDB]和 Slave[MyISAM]中使用不同的数据库引擎,实现读写的分离

分享/讲解/扩展思考

点名提问从第一节课到最后一节课分别学到了什么,直到同学们把所有的知识点都说出来并且保证无误。