0%

2018年3月10日 上午11:47

  1. 分布式是一种任务处理方式,判断的依据就是大任务是否拆分为小任务分给不同的机器
  2. 集群是一种物理形态,判断的依据就是是否有多台机器
  3. 分布式一定需要集群这种物理形态的支持

2018年3月10日 上午10:52

  1. 复制一个redis-2.8.0_1文件夹redis-2.8.0_2

  2. 修改redis-2.8.0_2的redis.conf的端口为6380

  3. 默认方式启动启动redis-2.8.0_1

  4. 指明配置文件位置的方式启动redis-2.8.0_2

  5. redis-cli方式启动redis-2.8.0_1

  6. redis-cli -p 6380方式启动redis-2.8.0_2

  7. 创建Common/RedisShardedPool类

    1. 复制RedisPool的内容进去
    2. 修改类关键字RedisPool为RedisShardedPool
    3. 多配置一个redis的ip和端口
    4. 然后初始化两个JedisShardInfo,代表两个redis
    5. 使用ShardedJedisPool去生成连接池
    6. 将连接对象从Jedis改为ShardedJedis
    7. RedisShardedPool帮你干了啥?
      1. 在放入值时,根据一致性hash算法选择合适的redis
      2. 在取值时,自动的判断值所在的redis,找到值并返回
  8. 创建util/RedisShardedPoolUtil类

    1. 将RedisPoolUtil的内容复制进去
    2. RedisPool更改为RedisShardedPool
    3. Jedis的类型改为ShardedJedis
  9. 找到所有调用RedisPoolUtil的类,替换成RedisShardedPoolUtil

2018年3月10日 上午10:20

这里要理解redis的一致性算法的原理,目的

  1. 目的:如果不使用一致性算法,当我们添加和删除redis缓存的时候,原先各个缓存中的数据会重新分配到各个redis缓存中。如果这时我们还使用原先数据和缓存的对应关系,还使用原先的hash算法,那么很大可能就会算错数据的位置。
  2. 如果我们使用一致性算法,首先明确的是:添加和删除redis缓存的时候,一定会是原先的命中率从100%下降,我们的目标就是在hash算法不变的情况下,能尽量的减少命中率的下降,这就是一致性算法的关键作用


Cache命中不到的话,就会极大地加大数据库的负载,因为请求会转到数据库中寻找数据


object映射到cache


删除之后,并不是原先的牵一发而动全身,但是也会出现命中不到的现象,如object4。这是他会

2018年3月9日 上午10:30

Index of /releases下载2.8版本

1
sudo tar -zxvf  redis-2.8.0.tar.gz

第一层目录下执行

1
2
sudo make
sudo make test

开启redis

1
2
3
cd src/
ls | grep redis
sudo redis-server

关闭(自动持久化):

1
redis-cli shutdown

更换端口(不操作redia.conf):

换端口启动:

1
sudo redis-server --port 6380

客户端换端口连接:

1
redis-cli -p 6380
1
redis-cli -p 6380 shutdown

更换端口(操作redis.conf):

redis-cli的各种操作依然要执行-p参数

指定ip连接:-h

1
redis-cli -p 6380 -h 127.0.0.1

配置redis密码:

2018年3月9日 上午10:07

参考文章:

Linux kill和kill-9区别
linux命令ps aux|grep xxx详解 - 人生设计师 - 博客园
每天一个linux命令(35):ln 命令 - peida - 博客园

关闭我已经自启的redis

mac下redis安装、设置、启动停止 - 漫夭 - 博客园

1
2
ps axu|grep redis  ## 查找redis-server的PID
kill -9 PID
1
2
3
4
5
6
7
8
9
10
11
## 启动redis-server,后台线程
AT8775:redis shoren$ redis-server /usr/local/redis/etc/redis.conf
## 启动成功
AT8775:redis shoren$ ps axu|grep redis
shoren 14948 0.0 0.0 2434840 760 s000 S+ 10:18上午 0:00.00 grep redis
shoren 14946 0.0 0.0 2452968 1492 ?? Ss 10:18上午 0:00.01 redis-server *:6379
## 关闭服务器
AT8775:redis shoren$ redis-cli shutdown
##关闭成功
AT8775:redis shoren$ ps axu|grep redis
shoren 14952 0.0 0.0 2435864 772 s000 S+ 10:19上午 0:00.01 grep redis

取消redis的开机自启

Mac 取消软件开机启动_百度经验
我先前通过brew安装了一个redis:Redis安装,并且我设置成了开机自启,所以我必须把开机自启关闭:

1
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.redis.plist

2018年3月9日 下午2:53

  1. 在pom.xml中引入jedis2.6.0版本
    1. 与redis连接的javaAPI
  2. 创建_common_RedisPool 类
    1. 变量要使用static类型,因为要在tomcat启动的时候就配置好连接池
    2. initPool()只使用一次,并且要在tomcat启动的时候就调用,所以要放在静态块中岁tomcat启动时就初始化pool
    3. 其中主要使用了我们引入的外部api
      1. JedisPoolConfig
      2. JedisPool
    4. 对外部使用者来说,我们上面的两个对象是隐藏的,只有一下三个方法用于操作JedisPool的pool对象
      1. getJedis
      2. returnBrokenResource
      3. returnResource
  3. 在mmall.prooerties中配置RedisPool的各种属性
    1. RedisPool中使用PropertiesUtil读取配置
    2. 都是连接池的配置或者是连接Redis的账户信息
  4. 书写main函数进行测试,看是否能将数据写入到redis中
  5. 创建_util_RedisPoolUtil工具类
    1. 利用RedisPool中放出来的三个方法,将需要的redis的命令进行封装,主要都包括
      1. 获取jedis实例
      2. 执行语句
      3. 放回连接池
  6. 书写main函数进行测试,通过打断点,单步进行观察

序列化,反序列化原因

  1. 我们现在需要将我们的用户session存储在redis中 ,但是redis中不能不能直接存储User对象,我们只能使用序列化的方法:将User对象序列化为json,然后用redis中的string类型进行存储

  2. 创建_util_JsonUtil类

    1. 配置序列化的各种属性
    2. 配置反序列化的各种属性
    3. 重点:
      1. 使用typeReference,解决List这类问题
      2. 在Intellij IDEA中使用Debug - bojiangzhou - 博客园
        1. 计算表达式功能
        2. 变量查看功能
      3. 参数中,使用Class<?>代替Class原因
        1. 我们在参数中要使用的class类型不确定,此时可以使用任意一个
        2. 但是,当我们参数中的类型与函数的返回值类型不是恒定不变的一对一的关系时,我们就只能使用Class<?>
      4. 我没有看6.9节的源码解析
  3. 在controller中将session的保存用redis缓存来代替

    1. session.getId()作为redis的key值
  4. 配置tomcat启动配置,设置两个tomcat,tomcat1、tomcat2

    1. 注意tomcat2的端口配置
    2. 即使这里设置了两个,但是真正运行的时候idea只能在一个tomcat上部署
  5. 复制整个项目,改个名字就行,然后用idea打开这个复制好的项目,选择new windows。然后,在这个项目中运行配置选择tomcat2,运行。

  6. 打开已经配置好对域名www.imooc.com负载均衡的nginx服务器

  7. 配置host,让域名www.imooc.com指向nginx的127.0.0.1

    1. 测试,ping www.imooc.com看是否指向127.0.0.1
    2. Reload nginx,因为nginx在负载均衡转发的时候,我们在分流的配置项中写的是www.imooc.com,而不是127.0.0.1。nginx在解析这里的www.imooc.com时,还是需要我们本机的host文件。所以,**配置host之后,一定要reload nginx**
  8. 在浏览器中访问www.imooc.com,看到tomcat1,Tomcat2随机访问

现在的问题是:当我们分别访问tomcat1、tomcat2时,双方的登录信息sessionid不能共享。也就是说,当tomcat1登录之后,tomcat2依然没有登录

  1. 创建_util_CookieUtil
    1. 利用Cookie对象来操作管理浏览器的sessionid
    2. 通过domain按域名划分cookie的共用范围
    3. 设置存在时间(或者销毁)
    4. 这个过程是如何与浏览器进行信息的传递呢?
      1. 就是我们servlet最原始的request+response完成与浏览器的交互过程
    5. cookie和session这篇文章很关键
  2. 当用户登录信息正确时,我们将使用CookieUtil的writeLoginToken向发出请求的浏览器发送一个名字为mmall_login_taken的cookie,值为sessionId。
    1. 如果不正确的话,服务器只会给浏览器一个Jsessonid,对于Jsessonid,是请求都会给,这就导致了每次的访问都会更改JsessionId的值
    2. JsessionId不等于session.getId()的值,JsessionId是一定存在的cookie,只要是个网站他就会返回给浏览器
  3. 重新发布两个相同的项目到两个tomcat中,打不开首页的处理方法
    1. 分别执行:mvn clean package -Dmaven.test.skip=true
    2. 别一块启动tomcat,分开启动
  4. 注意这时要用debug模式运行,而不是run,因为我们要打断点进行联调
    1. 在debug模式,我们的断点在更改之后,立即在下一次访问生效,不用重新启动tomcat
    2. 在debug模式,即使断点已经到来,我们依然可以在当前断点的后面增加断点,同样也是立即生效
  5. 现在就可以实现不同服务器共享session,其实准确点是共享cookie,这里的共享是按域名来划分,而不是按tomcat来划分,这是最根本的原理
    1. 可以在chrome_检查_Application/Cookies中查看登录之后,我们配置的cookie是否有了
  6. 现在只是修改了login.do,其他访问路径依然还是使用session.getAttribute。我们要session写法改成CookieUtil的写法
    1. login.do
      1. login.do的时候要使用RedisPoolUtil来写入redis当前用户的信息
    2. 其他的各种方法都是调用CookieUtil的readLoginToken来读取用户的信息
      1. 即要检查cookie有没有mmall.login.token,还要检查redis中是否真的有,双重验证。
    3. logout.do是使用delLoginToken方法
      1. 同时要使用RedisPoolUtil删除redis中对应的键值
  7. 创建_controller_common/SessionExpireFilter过滤器,用于在每次更新redis当前用的有效期
    1. 现在有两个有效期,一个是cookie的,一个是redis的,这两个缺一不可。
    2. 将过滤器这个组件加入到web.xml中
  8. 用redis来代替我们各自tomcat中的GuavaCache,因为两个tomcat的GuavaCache并不是共享的。
    1. 用户输入获取token的tomcat1,与用户最终通过输入taken来修改密码的tomcat2是不同的,这时Tomcat2就无法验证保存在tomcat1中的正确的taken
    2. 此时可以删除GuavaCache的工具类了

2018年3月8日 下午12:44

注:下文中提到配置文件可到:Learning.happymmall.com 下载


热部署
http线程池


登录信息session的共享

架构的演进和代码的演进过程


注:我们这里要重新解压缩新的tomcat,使webapps得ROOT也藐视tomcat的默认首页

2018年3月8日 下午12:17

概述:

通过maven命令的不同打包方式打包,打包发布不同的环境,省去了本地环境与线上环境不同要逐个改配置文件的麻烦

配置maven

pom.xml

创建文件夹,修改各自的配置

使用—P命令选择打包的环境

1
localhost:mmallv4.0 czh$ mvn clean package -Dmaven.test.skip=true -Pdev

在tomcat中发布不同的环境:



注:

  1. 此时如果发生更改也要点击import change
  2. profiles中我们只选择一个
  3. maven project中选定环境和我们通过—P命令进行打包的有啥区别:
    1. —P命令进行打包是打包在了当前项目目录下的target文件夹下
    2. maven project中选定环境是给我们run时,选定的发布在tomcat的版本

2018年3月8日 上午10:35

主要功能:

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。

官网:

lombok:Project Lombok
反编译软件:Java Decompiler 功能:class->java

lombok原理


注意:

  1. @data注解会自动生成toString,EqualsAndHashCode(默认全变量),get,set方法
  2. 我们一般不使用@data,而是使用:
    1
    2
    3
    4
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor

在项目中配置:





使用maven打包时跳过单元测试,生成class文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
localhost:mmallv4.0 czh$ mvn clean package -Dmaven.test.skip=true
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com:mmall:war:2.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 292, column 15
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mmall Maven Webapp 2.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ mmall ---
[INFO] Deleting /Users/czh/IdeaProjects/mmallv4.0/target
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ mmall ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 4 resources
[INFO] Copying 12 resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ mmall ---
[INFO] Compiling 70 source files to /Users/czh/IdeaProjects/mmallv4.0/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ mmall ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/czh/IdeaProjects/mmallv4.0/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ mmall ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ mmall ---
[WARNING] The POM for org.apache.maven:maven-plugin-api:jar:2.0.9 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-war-plugin:2.1.1:war (default-war) @ mmall ---
[INFO] Packaging webapp
[INFO] Assembling webapp [mmall] in [/Users/czh/IdeaProjects/mmallv4.0/target/mmall]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/czh/IdeaProjects/mmallv4.0/src/main/webapp]
[INFO] Webapp assembled in [647 msecs]
[INFO] Building war: /Users/czh/IdeaProjects/mmallv4.0/target/mmall.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.264s
[INFO] Finished at: Thu Mar 08 11:16:04 CST 2018
[INFO] Final Memory: 23M/369M
[INFO] ------------------------------------------------------------------------
localhost:mmallv4.0 czh$


最后,将class文件用反编译软件打开