淘淘商城第十四天
讲师:入云龙
1 课程计划
1、把系统部署到生产环境。切换到redis集群、solr集群
2、安装mysql
3、项目部署,使用tomcat的热部署。
4、项目总结
5、面试中遇到的问题
2 Mysql的安装
2.1 查看mysql的安装路径:
[root@bogon ~]# whereis mysql
mysql: /usr/bin/mysql /usr/lib/mysql/usr/share/mysql /usr/share/man/man1/mysql.1.gz
2.2 查看mysql的安装包:
[root@bogon ~]# rpm -qa|grep mysql
mysql-community-client-5.6.26-2.el6.i686
mysql-community-release-el6-5.noarch
mysql-community-common-5.6.26-2.el6.i686
mysql-community-libs-5.6.26-2.el6.i686
mysql-community-server-5.6.26-2.el6.i686
[root@bogon ~]#
2.3 卸载mysql
[root@bogon ~]# yum remove mysql
删除mysql的数据库文件:删除/var/llib/mysql目录
2.4 安装mysql
第一步:从oracle官方网站下载linux系统对应的mysql的yum源包。
第二步:把yum源包上传到linux,安装。
[root@bogon ~]# yum localinstallmysql-community-release-el6-5.noarch.rpm
[root@bogon ~]# yum install mysql-server
第三步:启动mysql
[root@bogon ~]# service mysqld start
第四步:给root用户设置密码
[root@bogon ~]# /usr/bin/mysqladmin -u rootpassword 'root'
第五步:远程连接授权
GRANT ALL PRIVILEGESON *.* TO 'myuser'@'%'IDENTIFIED BY 'mypassword'WITH GRANT OPTION;
注意:'myuser'、'mypassword' 需要替换成实际的用户名和密码。
mysql> GRANT ALL PRIVILEGES ON *.* TO'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
2.5 Rpm安装法
如果没有网络环境可以使用参考资料中的mysql-rpm文件夹下的mysql安装包来安装。
[root@bogon mysql-rpm]# rpm -ivhmysql-community-*
安装后,启动服务、设置密码、远程授权后既可以使用。
3 系统部署
3.1 域名的分配
一级域名:taotao.com
二级域名:www.taotao.com
系统 | 域名 |
Taotao-manager | manager.taotao.com |
Taotao-rest | rest.taotao.com |
Taotao-portal | www.taotao.com |
Taotao-search | search.taotao.com |
Taotao-sso | sso.taotao.com |
Taotao-order | order.taotao.com |
所有的域名应该指向反向代理服务器。
3.2 需要几台服务器部署系统
服务器规划:
图片服务器:1台虚拟机
Redis集群:1台
Solr集群:1台
Mysql:1台
Taotao-manager:1台
Taotao-porta:1台
Taotao-rest、taotao-search、taotao-sso、taotao-order:1台(4个tomcat实例)
Nginx:1台
共需要8台虚拟机。
3.3 Taotao-manager部署
3.3.1 要求的环境
Linux系统 centos6.4
Jdk 1.7版本
Tomcat 7
3.3.2 Tomcat热部署
3.3.2.1 Tomcat的配置
我们需要实现热部署,自然就需要通过maven操作tomcat,所以就需要maven取得操作tomcat的权限,现在这一步就是配置tomcat的可操作权限.
在tomcat的安装目录下,修改conf / tomcat-user.xml文件,在<tomcat-users>节点下面增加如下配置:
<role rolename="manager-gui" /> <role rolename="manager-script" /> <user username="tomcat" password="tomcat" roles="manager-gui, manager-script"/> |
3.3.2.2 使用maven插件实现热部署
需要使用maven的tomcat插件。Apache官方提供的tomcat插件。
使用maven打包——》上传——热部署一气呵成。
Maven的配置
修改项目的pom.xml文件,在<build> 节点下面增加如下配置:tomcat7的配置
<build> <plugins> <!-- 配置Tomcat插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>8081</port> <path>/</path> <url>http://192.168.25.136:8080/manager/text</url> <username>tomcat</username> <password>tomcat</password> </configuration> </plugin> </plugins> </build> |
3.3.2.3 热部署
热部署之前,修改配置文件中的数据库配置、调用服务的配置为生产环境需要的ip及端口。
执行以下命令:
初次部署可以使用 "tomcat7:deploy" 命令
如果已经部署过使用 "tomcat7:redeploy" 命令
部署跳过测试:
tomcat7:redeploy -DskipTests
3.4 服务层部署
部署四个工程包括taotao-rest、taotao-search、taotao-sso、taotao-order
第一步:配置4个tomcat实例
taotao-rest、8080
taotao-search、8081
taotao-sso、8082
taotao-order、8083
第二步:修改项目中的db配置及调用服务的配置,修改ip地址及端口号。
第三步:修改pom文件指定工程要部署的路径,及用户名、密码。
3.5 Taotao-portal的部署
第一步:修改taotao-portal中所有的localhost包括配置文件中、js中。
第二步:修改pom文件指定部署的服务器及用户名密码
第三步:安装服务器及tomcat。
第四步:部署taotao-portal
3.6 Nginx配置
#user nobody; worker_processes 1;
#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;
#pid logs/nginx.pid;
events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on; #tcp_nopush on;
#keepalive_timeout 0; keepalive_timeout 65;
#gzip on;
upstream manager.taotao.com { server 192.168.25.135:8080; } upstream rest.taotao.com { server 192.168.25.136:8080; } upstream search.taotao.com { server 192.168.25.136:8081; } upstream sso.taotao.com { server 192.168.25.136:8082; } upstream order.taotao.com { server 192.168.25.136:8083; } upstream www.taotao.com { server 192.168.25.137:8080; } server { listen 80; server_name manager.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://manager.taotao.com; index index.html index.htm; } } server { listen 80; server_name rest.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://rest.taotao.com; index index.html index.htm; } } server { listen 80; server_name search.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://search.taotao.com; index index.html index.htm; } } server { listen 80; server_name sso.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://sso.taotao.com; index index.html index.htm; } } server { listen 80; server_name order.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://order.taotao.com; index index.html index.htm; } } server { listen 80; server_name www.taotao.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / { proxy_pass http://www.taotao.com; index index.html index.htm; } }
}
|
4 系统部署完成
5 补充知识点
日志处理:
第一步:
需要引入log4j、Slf4j的jar包。
第二步:需要有log4j.properties配置文件。
http://blog.csdn.net/edward0830ly/article/details/8250412
log4j.rootLogger=DEBUG, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. #log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n # Print the date in ISO 8601 format log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=taotao.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n # Print only messages of level WARN or above in the package com.foo. log4j.logger.com.foo=WARN |
public class JedisTest {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisTest.class);
@Test public void testJedisSingle() { //创建一个jedis的对象。 Jedis jedis = new Jedis("192.168.25.153", 6379); //调用jedis对象的方法,方法名称和redis的命令一致。 jedis.set("key1", "jedis test"); String string = jedis.get("key1"); System.out.println(string); //关闭jedis。 jedis.close(); }
/** * 使用连接池 */ @Test public void testJedisPool() { //创建jedis连接池 JedisPool pool = new JedisPool("192.168.25.153", 6379); //从连接池中获得Jedis对象 Jedis jedis = pool.getResource(); String string = jedis.get("key1"); System.out.println(string); //关闭jedis对象 jedis.close(); pool.close(); }
/** * 集群版测试 * <p>Title: testJedisCluster</p> * <p>Description: </p> */ @Test public void testJedisCluster() { LOGGER.debug("调用redisCluster开始"); HashSet<HostAndPort> nodes = new HashSet<>(); nodes.add(new HostAndPort("192.168.25.153", 7001)); nodes.add(new HostAndPort("192.168.25.153", 7002)); nodes.add(new HostAndPort("192.168.25.153", 7003)); nodes.add(new HostAndPort("192.168.25.153", 7004)); nodes.add(new HostAndPort("192.168.25.153", 7005)); nodes.add(new HostAndPort("192.168.25.153", 7006)); LOGGER.info("创建一个JedisCluster对象"); JedisCluster cluster = new JedisCluster(nodes); LOGGER.debug("设置key1的值为1000"); cluster.set("key1", "1000");
LOGGER.debug("从Redis中取key1的值"); String string = cluster.get("key1"); System.out.println(string); cluster.close(); try { int a = 1/0; } catch (Exception e) { LOGGER.error("系统发送异常", e); } }
/** * 单机版测试 * <p>Title: testSpringJedisSingle</p> * <p>Description: </p> */ @Test public void testSpringJedisSingle() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml"); JedisPool pool = (JedisPool) applicationContext.getBean("redisClient"); Jedis jedis = pool.getResource(); String string = jedis.get("key1"); System.out.println(string); jedis.close(); pool.close(); }
@Test public void testSpringJedisCluster() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml"); JedisCluster jedisCluster = (JedisCluster) applicationContext.getBean("redisClient"); String string = jedisCluster.get("key1"); System.out.println(string); jedisCluster.close(); } } |
6 项目总结
总结淘淘商城中用到的技术点:
6.1 第一天:项目工程搭建。
1、使用maven构建工程。Maven的继承、聚合、依赖管理。
2、Svn的使用,svn上传下载代码。
6.2 第二天:ssm框架整合。
1、mybatis逆向工程。
2、后台管理系统搭建,前台技术使用EasyUI框架。了解easyUI的dategrid的使用方法。
6.3 第三天:实现商品添加。
1、商品类目选择。EasyUI的异步tree的使用方法。
2、图片服务器的搭建。使用ftp+http配合,实现图片服务。ftp服务使用vsftpd实现,http服务使用nginx实现。
3、KindEditor富文本编辑器的使用方法。
6.4 第四天:规格参数实现。
1、规格参数的解决方案。
a) 方案一:创建多个表进行关联实现商品类目。
b) 方案二:使用模板方式实现。
2、java对象、json之间的转换。
6.5 第五天:前台工程搭建。
1、理解分布式系统架构思想。
2、Jsonp解决ajax跨域调用的问题。
6.6 第六天:CMS系统的实现
1、CMS系统的实现思路
2、Httpclient的使用方法
3、首页大广告位的实现
6.7 第七天:内容系统添加缓存
1、redis的使用方法及redis集群的搭建
2、系统中添加缓存逻辑
3、缓存的同步方法。
6.8 第八天:搜索功能实现
1、solr服务在linux环境的搭建
2、使用solr实现搜索功能。
3、索引库中商品的同步
6.9 第九天:商品详情页面实现
1、商品详情页面内容异步加载
2、规格参数按需加载
3、商品详情页面添加缓存及缓存同步
6.10 第十天:单点登录系统实现
1、服务接口的开发
2、在分布式环境中使用redis实现session共享
3、使用cookie在多个系统中共享。
4、拦截器的使用方法
6.11 第十一天:购物车、订单
1、使用cookie保存购物车信息
2、创建订单系统。发布服务,支持post请求提交json格式的数据。
3、在用户提交订单之前,检查用户的登录状态(拦截器)
6.12 第十二天:nginx安装、配置
1、nginx的虚拟机的配置
2、Nginx的反向代理
3、Nginx的负载均衡
4、Nginx的高可用
6.13 第十三天:solr集群的搭建、系统部署
1、solrCloud的搭建。Zookeeper的配置、solr集群的分片。
2、Mysql数据库在linux环境的安装
3、使用maven进行系统的热部署。
6.14 第十四天:项目总结
第一天:。。。。递归中。。
7 电商活动解决方案
7.1 电商活动倒计时方案:
1、确定一个基准时间。可以使用一个sql语句从数据库中取出一个当前时间。SELECTNOW();
2、活动开始的时间是固定的。
3、使用活动开始时间-基准时间可以计算出一个秒为单位的数值。
4、在redis中设置一个key(活动开始标识)。设置key的过期时间为第三步计算出来的时间。
5、展示页面的时候取出key的有效时间。Ttl命令。使用js倒计时。
6、一旦活动开始的key失效,说明活动开始。
7、需要在活动的逻辑中,先判断活动是否开始。
7.2 秒杀方案:
1、把商品的数量放到redis中。
2、秒杀时使用decr命令对商品数量减一。如果不是负数说明抢到。
一旦返回数值是负数说明商品已