Linux部署配置JDK,mysql,nginx,redis,mycat,zookeeper

1.1 Linux常用命令:

1.1.1 CD命令集

ifconfig/ip addr 检查IP地址
pwd 检查当前的位置
tab键 自动补齐(注意唯一性)
cd命令是linux中最基本的命令语句,必须熟练掌握
cd / 返回根目录
cd ~ 用户主目录
cd . 当前目录
cd …返回到上一级目录
cd /usr/ 进入到usr目录
cd – 返回上一个目录
cd 直接回家

1.1.2 ls目录和文件**

ls –l 详细格式,文件权限,时间
ll 和ls –l作用相同
ls *.txt 查看所有的txt类型文档

1.1.3 目录操作**

mkdir 创建目录
mkdir a 创建 a目录
mkdir -p a/b 创建 a目录,并在a目录里创建b目录
mkdir -m 777 c 创建一个权限为777的C目录
rmdir 删除目录(如果目录里有文件,则不能用此命令)

1.1.4 vi/vim创建/查看/编辑文件**

命令行:Esc切换到命令行模式。
编辑模式:
按i,在光标前开始编辑
按a,在光标后开始编辑
按o,在当前行的下一行开始编辑
按u, 撤销之前的操作
底行模式:按 shift+:冒号。
:q! 不保存退出
:wq 保存退出
:/world 从当前光标处,向上查找world关键字
:?world 从当前光标处,向后查找world关键字

1.1.5 删除文件**

rm 删除文件
rm n.txt 提示y删除n放弃
rm –f n.txt 不提示
rm –rf dirname 不提示递归删除目录下所以内容
rm –rf * 删除所有文件
rm –rf /* 删除所有子目录所有和文件

1.1.6 复制和移动文件**

cp复制文件
cp nginx.conf n.txt
cp –R tomcat1 tomcat2 #复制整个目录
mv 修改文件名,移动文件
mv n.txt m.txt 修改文件名称

1.1.7 浏览文件**

cat 输出文件所有的内容
more 输出文档所有的内容,分页输出,空格浏览下一屏,q退出
less 用法和more相同,只是通过PgUp、PgOn键来控制
tail 用于显示文件后几号,使用频繁
tail -10 nginx.conf 查看nginx.conf的最后10行
tail –f nginx.conf 动态查看日志,方便查看日志新增的信息
ctrl+c 结束查看

1.1.8 打包命令**

tar命令位于/bin目录下,它能够将用户所指定的文件或目录打包成一个文件,但不做压缩。一般Linux上常用的压缩方式是选用tar将许多文件打包成一个文件,再以gzip压缩命令压缩成name.tar.gz的文件。
-c 创建一个新的tar文件
-v 显示运行过程的信息
-f 指定文件名
-z 调用gzip压缩命令进行压缩
-t 查看压缩文件的内容
-x 解开tar文件
tar –cvf n.tar ./* 压缩当前目录下的所有文件和目录,文件名为n.tar
tar –xvf n.tar 解压压缩包中的文件到当前目录(如果长时间未解压成功 Ctrl+C推出)
tar –cvzf m.tar.gz ./* 压缩文件
tar -zxvf m.tar.gz 解压m.tar文件到当前目录

1.1.9 grep命令**

grep root /etc/passwd 在文件中查找关键字root
grep root /etc/passwd –-color 高亮显示
grep root /etc/passwd –A5 –B5 高亮显示,A后5行,B
grep -n root /etc/passwd 查找并显示行数
grep -v root /etc/passwd 取反,查出不含root的数据

2.1 JDK安装及配置

2.1.1上传安装包

说明:将JDK安装包上传到指定文件目录下/usr/local/src下
在这里插入图片描述
命令:

tar -xvf jdk-7u51-linux-x64.tar.gz

解压到当前目录即可

2.1.2配置环境变量

说明:修改Linux系统中环境变量需要修改/etc/profile文件
命令:

vim /etc/profile

配置文件变量

#set java env
JAVA_HOME=/usr/local/src/java/jdk1.7.0_51
JAVA_BIN=/usr/local/src/java/jdk1.7.0_51/bin
PATH=$JAVA_HOME/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JAVA_BIN PATH CLASSPATH

配置完后,让环境变量生效命令:

source /etc/profile

2.1.3 检查jdk是否生效

命令:

java -version
在这里插入图片描述
如图,即配置成功!

3.1 mysql安装及配置

3.1.1 安装mariadb数据库

同上,可以使用安装包直接上传,或者使用yum命令:

yum install mariadb-server

在这里插入图片描述
在这里插入图片描述

3.1.2 配置数据库

数据库操作命令

1.启动数据库命令 systemctl start mariadb

2.停止数据库命令 systemctl stop mariadb

3.重启数据库命令 systemctl restart mariadb

配置命令:

mysql_secure_installation

在这里插入图片描述
在这里插入图片描述

3.1.3 数据库登录

在这里插入图片描述

3.1.4 设定数据库权限

在这里插入图片描述
修改用户权限列表
在这里插入图片描述

刷新数据库权限

命令:

flush privileges;
数据库安装成功

4.1 Linux防火墙说明

4.1.1 防火墙配置

1).配置以后不开启防火墙
命令

systemctl disable firewalld.service
** 2).配置以后开启防火墙2).配置以后开启防火墙**
命令
systemctl enable firewalld.service

3).检查防火墙工作状态

firewall-cmd --state
** 4).关闭/启动防火墙**
systemctl stop firewalld.service
systemctl start firewalld.service
在这里插入图片描述

4.1.2 指定端口号开放

	firewall-cmd --zone=public --add-port=3306/tcp --permanent

命令含义:
					–zone #作用域
					–add-port=80/tcp #添加端口,格式为:端口/通讯协议
					–permanent #永久生效,没有此参数重启后失效

5.1 tomcat启动程序

关闭tomcat服务器
命令
在这里插入图片描述

5.1.1 通过脚本同时启动多台tomcat服务器

命令

vim start.sh
编辑文件

#!/bin/sh
nohup java -jar 8081.war -> 8081.log &
nohup java -jar 8082.war -> 8082.log &
nohup java -jar 8083.war -> 8083.log &

运行程序

sh start.sh

6.1 nginx配置及安装

6.1.1 下载或上传NGINX文件

下载安装包命令:
在这里插入图片描述
在这里插入图片描述

6.1.2nginx路径说明

说明: nginx的环境配置有2个环境.
环境1: /usr/local/src/nginx 该路径是nginx的源文件路径 主要负责编译/安装等工作 (安装)
环境2: /usr/local/nginx 该路径是nginx的工作路径 主要实现反向代理配置工作 (工作)

6.1.3 安装nginx

命令:

./configure
在这里插入图片描述

命令1:make
命令2: make install

查看位置
命令:
在这里插入图片描述

6.1.4 启动nginx

在这里插入图片描述
在这里插入图片描述
命令

1.启动nginx ./nginx
2.重启nginx ./nginx -s reload
3.关闭nginx ./nginx -s stop

安装成功!

6.1.5修改nginx配置信息

修改配置文件 nginx.conf 路径:/usr/local/nginx/conf目录
#配置图片服务器

server {
	listen 80;
	server_name  image.jt.com;

	location / {
		#配置反向代理的路径
		root  /usr/local/src/images;
	}
}

#配置域名代理
server {
	listen 80;
	server_name  manage.jt.com;

	location / {
		#代理tomcat服务器
		proxy_pass  http://tomcats;
	}
}

#配置tomcat集群  默认是轮询策略
upstream tomcats {
	server localhost:8081;
	server localhost:8082;
	server localhost:8083;
}

修改完后重启服务器

7.1 主从数据库设计

7.1.1 数据库热备份原理

在这里插入图片描述

工作原理说明:
1.数据库主库将更新的数据信息写入到二进制日志文件中.
2.数据库从库通过IO线程去主库中获取二进制文件修改内容. 之后写入到中继日志中
3.数据库从库中的Sql线程读取中继日志中的信息,实现数据的同步.
并且为了降低组件之间的耦合性,采用异步的方式处理.

7.1.2 准备第二台Linux操作系统

在这里插入图片描述
修改虚拟机IP地址
规定: 主机IP地址 192.168.126.129 从机 192.168.126.130
1).进入修改IP地址目录
命令

cd /etc/sysconfig/network-scripts/

在这里插入图片描述
2).修改配置文件信息

在这里插入图片描述
3).重置网卡

在这里插入图片描述

7.1.3 数据库主从配置

开启数据库二进制文件
修改配置文件

vim /etc/my.cnf
在这里插入图片描述
修改之后,重启数据库
在这里插入图片描述
开启从库二进制文件
在这里插入图片描述

7.1.4 利用sqlYog工具链接从库

数据库中执行命令
在这里插入图片描述
实现主从挂载

/130是从机 实现主从的挂载 host/port/user/password/二进制文件/位置/
change MASTER to MASTER_HOST=“192.168.126.129”, MASTER_PORT=3306,
MASTER_USER=“root”, MASTER_PASSWORD=“root”,
MASTER_LOG_FILE=“mysql-bin.000001”, MASTER_LOG_POS=245;

/开启主从服务/
start slave;

/检查主从同步状态/
show SLAVE status;

主从状态说明
在这里插入图片描述

8.1 mycat数据库代理服务器

8.1.1读写分离说明

在这里插入图片描述

8.1.2 mycat安装

官网下载

tar -xvf Mycat-server-1.7.0-DEV-20170416134921-linux.tar.gz
下载解压即可

8.1.3配置文件

server.xml配置
注意事项: 数据库代理的端口号 8066端口

<!--用户标签-->
	<user name="root">
		<property name="password">root</property>
		<!--与schema.xml中的配置相同 注意数据库的大小写-->
		<property name="schemas">jtdb</property>
	</user>

	<user name="user">
		<property name="password">user</property>
		<property name="schemas">jtdb</property>
		<property name="readOnly">true</property>
	</user>

schema.xml
配置说明:该配置表示了读写分离/负载均衡的设置.

<writeHost host="hostM1" url="192.168.126.129:3306" user="root" password="root">
		<!--读数据库1-->
		<readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" />
		<!--读数据库2-->
		<readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" />
		
	</writeHost>

8.1.4 启动mycat

在这里插入图片描述
启动效果

在这里插入图片描述
修改java配置文件里的数据源配置

spring:
  datasource:
    #引入druid数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    #driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.126.129:8066/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

8.1.5 数据库双主热备

在这里插入图片描述

利用sqlYog主从挂载

/我之前是主库 现在是从库/
CHANGE MASTER TO MASTER_HOST=“192.168.126.130”,
MASTER_PORT=3306, MASTER_user=“root”, MASTER_PASSWORD=“root”,
MASTER_LOG_FILE=“mysql-bin.000001”, MASTER_LOG_POS=482;

/* 启动主从服务*/
start slave

show SLAVE status;

8.1.7配置数据库高可用

说明: 当其中有一台数据库宕机之后,用户依然可以正确的访问数据库不受任何影响,(实现了故障迁移).主要数据库能够正常的工作,则重新启动数据库之后则可以实现自动的数据的同步.

配置文件修改:
schema.xml

	<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	
	<!--name属性是自定义的  dataNode表示数据库的节点信息  jtdb表示逻辑库-->
	<schema name="jtdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="jtdb"/>

	<!--定义节点名称/节点主机/数据名称-->
	<dataNode name="jtdb" dataHost="localhost1" database="jtdb" />
		<!--参数介绍-->
		<!--balance 0表示所有的读操作都会发往writeHost主机 -->  
		<!--1表示所有的读操作发往readHost和闲置的主节点中-->
		<!--writeType=0 所有的写操作都发往第一个writeHost主机-->	
		<!--writeType=1 所有的写操作随机发往writeHost中-->
		<!--dbType 表示数据库类型 mysql/oracle-->
		<!--dbDriver="native"  固定参数 不变-->
		<!--switchType=-1 表示不自动切换, 主机宕机后不会自动切换从节点-->
		<!--switchType=1  表示会自动切换(默认值)如果第一个主节点宕机后,Mycat会进行3次心跳检测,如果3次都没有响应,则会自动切换到第二个主节点-->
		<!--并且会更新/conf/dnindex.properties文件的主节点信息 localhost1=0 表示第一个节点.该文件不要随意修改否则会出现大问题-->
	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<!--心跳检测策略-->
		<heartbeat>select 1</heartbeat>

		<!--配置第一台主机主要进行写库操作,在默认的条件下Mycat主要操作第一台主机在第一台主机中已经实现了读写分离.因为默认写操作会发往137的数据库.读的操作默认发往141.如果从节点比较忙,则主节点分担部分压力.
		-->
		<writeHost host="hostM1" url="192.168.126.129:3306" user="root" password="root">
			<!--读数据库1-->
			<readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" />
			<!--读数据库2-->
			<readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" />
			
		</writeHost>

			<!--定义第二台主机 由于数据库内部已经实现了双机热备.-->
			<!--Mycat实现高可用.当第一个主机137宕机后.mycat会自动发出心跳检测.检测3.-->
			<!--如果主机137没有给Mycat响应则判断主机死亡.则回启东第二台主机继续为用户提供服务.-->
			<!--如果137主机恢复之后则处于等待状态.如果141宕机则137再次持续为用户提供服务.-->
			<!--前提:实现双机热备.-->
		
		<writeHost host="hostM2" url="192.168.126.130:3306" user="root" password="root">-
			<!--读数据库1-->
			<readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" />
			<!--读数据库2-->
			<readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" />
		</writeHost>
		
	</dataHost>
</mycat:schema>

完成!!!

9.1 Redis缓存

9.1.1缓存机制说明

在这里插入图片描述

9.1.2 redis安装

在这里插入图片描述
上传解压文件.

说明:在redis的根目录中执行
1). make
2). make install

在这里插入图片描述

9.1.3 redis配置文件

编辑redis.conf

vim redis.conf

修改ip绑定
在这里插入图片描述

修改保护模式
在这里插入图片描述
开启后台启动
在这里插入图片描述

9.1.4 redis服务命令

1.启动redis redis-server redis.conf
2.进入客户端 redis-cli -p 6379
3.关闭redis redis-cli -p 6379 shutdown
简化操作: 如果操作的redis是默认的端口 则可以省略不写.

9.1.5 redis入门案例说明

导入jar包

<!--spring整合redis -->
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
</dependency>

编辑测试类

	package com.jt.test;

import org.junit.jupiter.api.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;

public class TestRedis {
	
	/**
	 * 1.spring整合redis
	 * 报错说明:
	 * 	1).如果测试过程中报错 则检查redis配置文件  改3处
	 *  2).检查redis启动方式   redis-server redis.conf
	 *  3).检查Linux的防火墙
	 * 	做完的 测试其他命令.
	 */
	@Test
	public void testString01() {
		
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		//2.操作redis
		jedis.set("a", "redis入门案例");
		String value = jedis.get("a");
		System.out.println(value);
	}
	
	@Test
	public void testString02() {
		
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		//2.判断当前数据是否存在
		if(jedis.exists("a")) {
			System.out.println(jedis.get("a"));
		}else {
			
			jedis.set("a", "测试是否存在的方法");
		}
		
	}
	
	/**
	 * 1.能否简化是否存在的判断
	 * 2.如果该数据不存在时修改数据,否则不修改
	 * setnx方法:  只有当数据不存在时赋值.
	 */
	@Test
	public void testString03() {
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.setnx("a", "测试setnx方法1");
		jedis.setnx("a", "测试setnx方法2");
		System.out.println(jedis.get("a"));
	}
	
	/**
	 * 为数据添加超时时间
	 * @throws InterruptedException 
	 * setex方法  保证赋值操作和添加超时时间的操作的原子性
	 * 原子性: 要么同时成功,要么同时失败(类似事务)
	 */
	@Test
	public void testString04() throws InterruptedException {
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		
		jedis.set("a", "aaaa"); //如果程序报错,则超时方法将不会执行,改数据将永不超时
		//程序报错,意外终止!!!!!!!
		jedis.expire("a", 20);	//添加超时时间    不是原子性操作
		Thread.sleep(2000);
		System.out.println("剩余存活时间:"+jedis.ttl("a"));
		
		//2.实现原子性操作
		jedis.setex("b", 20, "原子性测试");
		System.out.println(jedis.get("b"));
		
	}
	
	
	/**
	 *
	 * 1.只有数据不存在时允许修改
	 * 2.要求实现添加超时时间,并且是原子性操作
	 * SetParams 参数说明:
	 * 	1.NX   只有key不存在时才能修改
	 * 	2.XX   只有key存在时,才能修改
	 *  3.PX   添加的时间单位是毫秒
	 *  4.EX   添加的时间单位是秒
	 */
	@Test
	public void testString05(){
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		SetParams params = new SetParams();
		params.xx().ex(20);
		jedis.set("aa", "测试A", params);	
		jedis.set("aa", "测试B", params);	
		System.out.println(jedis.get("aa"));
	}
	
	
	
	/**
	 * 存储一类数据时,可以使用hash.
	 */
	@Test
	public void testHASH(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.hset("user", "name", "tomcat");
		jedis.hset("user", "id", "100");
		System.out.println(jedis.hgetAll("user"));
	}
	
	
	@Test
	public void testList(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.lpush("list", "1","2","3","4");
		System.out.println(jedis.rpop("list"));
		
	}
	
	//控制事务
	@Test
	public void testTx(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		
		Transaction transaction = jedis.multi();		//2.开启事务
		try {
			transaction.set("aaa", "aaa");
			transaction.set("bbb", "bbbbb");
			transaction.set("ccc", "cccccc");
			transaction.exec();			//事务提交
		} catch (Exception e) {
			e.printStackTrace();
			transaction.discard();		//事务回滚
		}
	}
}
	

9.1.6 redis整合

说明:将jedis对象交给spring容器进行管理.之后哪里需要直接注入即可. 步骤:
1.编辑redis.properties文件,指定redis节点的ip:port
2.由于redis比较重要,很多业务系统都需要调用,所以将redis整合写入common
3.通过配置类(配置文件)形式整合redis.

编辑redis.properties文件

redis.host=192.168.126.129
redis.port=6379

编辑配置类

	@Configuration 	//我是一个配置类    一般都会与@Bean联用
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
	
	@Value("${redis.host}")
	private String host;
	@Value("${redis.port}")
	private Integer port;
	
	//将返回值的结果交给spring容器进行管理,如果以后想要使用该对象则可以直接注入.
	@Bean
	public Jedis jedis() {
		
		return new Jedis(host, port);
	}
	
}

json转化API

package com.jt.test;

import java.util.Date;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;

public class TestObjectMapper {
	
	//改对象就是工具api  有且只有一份即可.并且不允许别人修改.
	private static final ObjectMapper MAPPER = new ObjectMapper();
	/**
	 * 目的: 实现对象与json串之间的转化
	 * 步骤1:  将对象转化为json
	 * 步骤2:  将json转化为对象 
	 * 利用ObjectMapper 工具API实现
	 * @throws JsonProcessingException 
	 */
	@Test
	public void test01() throws JsonProcessingException {
		
		ItemDesc itemDesc = new ItemDesc();
		itemDesc.setItemId(101L).setItemDesc("json转化测试")
		.setCreated(new Date()).setUpdated(itemDesc.getCreated());
		
		//1.将对象转化为JSON   调用的是对象的get方法
		String json = MAPPER.writeValueAsString(itemDesc);
		System.out.println(json);
		
		//2.将json转化为对象   传递需要转化之后的class类型   调用是对象的set方法
		ItemDesc itemDesc2 = MAPPER.readValue(json, ItemDesc.class);
		System.out.println(itemDesc2.getItemDesc());
	}
}

9.1.7 AOP实现redis缓存

入门案例

//1.将对象交给容器管理
@Component
//2.定义aop切面
@Aspect
public class CacheAOP {
	
	//公式:   切面 = 切入点表达式 + 通知方法.
	/**
	 * 业务需求: 要求拦截ItemCatServiceImpl类中的业务
	 * @Pointcut 切入点表达式 可以理解为就是一个if判断,只有满足条件,才能执行通知方法.
	 */
	//@Pointcut("bean(itemCatServiceImpl)")  //按类匹配,控制的粒度较粗   单个bean
	//@Pointcut("within(com.jt.service..*)")  //按类匹配,控制的粒度较粗     多个bean
	@Pointcut("execution(* com.jt.service..*.*(..))") //细粒度的匹配方式
	public void pointCut() {
		
	}
	
	//joinPoint 方法执行切恰好被切入点表达式匹配,该方法的执行就称之为连接点.
	@Before("pointCut()")
	public void before(JoinPoint joinPoint) {
		System.out.println("我是前置通知!!!!");
		String typeName = 
				joinPoint.getSignature().getDeclaringTypeName();
		String methodName = joinPoint.getSignature().getName();
		Object[] objs = joinPoint.getArgs();
		Object target = joinPoint.getTarget();
		System.out.println("方法执行的全路径为:"+typeName+"."+methodName);
		System.out.println("获取方法参数:"+objs);
		System.out.println("获取目标对象:"+target);
	}
	
	
	//添加环绕通知  可以控制目标方法执行 要求添加参数
	@Around("pointCut()")
	public Object around(ProceedingJoinPoint joinPoint) {
		
		System.out.println("我是环绕通知开始");
		try {
			//Object result = joinPoint.proceed();
			System.out.println("我是环绕通知结束");
			return null;
		} catch (Throwable e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}  //指定目标方法
		
	}
	
}

实现AOP 缓存处理
自定义注解

@Target(ElementType.METHOD)	//标识注解 对谁生效
@Retention(RetentionPolicy.RUNTIME) //注解使用的有效期
public @interface CacheFind {
	
	public String key();			  //标识存入redis的key的前缀
	public int seconds() default 0;  //标识保存的时间 单位是秒
	
}

注解标识

在这里插入图片描述

AOP实现缓存业务处理
	package com.jt.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jt.anno.CacheFind;
import com.jt.util.ObjectMapperUtil;

import redis.clients.jedis.Jedis;

//1.将对象交给容器管理
@Component
//2.定义aop切面
@Aspect
public class CacheAOP {
	
	@Autowired(required = false)
	private Jedis jedis;
	/**
	 * 实现思路:  拦截被@CacheFind标识的方法 之后利用aop进行缓存的控制
	 * 通知方法:  环绕通知
	 * 实现步骤:
	 * 		1.准备查询redis的key   ITEM_CAT_LIST::第一个参数
	 *      2.@annotation(cacheFind) 动态获取注解的语法.
	 *        拦截指定注解类型的注解并且将注解对象当做参数进行传递.
	 */
	@SuppressWarnings("unchecked")
	@Around("@annotation(cacheFind)")
	public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) {
		
		//1.获取用户注解中的key     ITEM_CAT_LIST::0
		String key = cacheFind.key();
		//2.动态获取第一个参数当做key
		String firstArg = joinPoint.getArgs()[0].toString();
		key += "::"+firstArg; 
		
		Object result = null;
		//3.根据key查询redis.
		if(jedis.exists(key)) {
			
			//根据redis获取数据信息
			String json = jedis.get(key);
			//如何获取返回值类型
			MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
			result = ObjectMapperUtil.toObject(json, methodSignature.getReturnType());
			System.out.println("aop查询redis缓存");
		}else {
			//如果key不存在,则证明是第一次查询.  应该查询数据库
			try {
				result = joinPoint.proceed(); //目标方法返回值
				System.out.println("AOP查询数据库获取返回值结果");
				//将数据保存到redis中
				String json = ObjectMapperUtil.toJSON(result);
				int seconds = cacheFind.seconds();
				if(seconds>0) 
					jedis.setex(key, seconds, json);
				else 
					jedis.set(key, json); 
				
			} catch (Throwable e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		return result;
	}

	
	
	
	
	
	
	
	
	//公式:   切面 = 切入点表达式 + 通知方法.
	/**
	 * 业务需求: 要求拦截ItemCatServiceImpl类中的业务
	 * @Pointcut 切入点表达式 可以理解为就是一个if判断,只有满足条件,才能执行通知方法.
	 */
	/**
	//@Pointcut("bean(itemCatServiceImpl)")  //按类匹配,控制的粒度较粗   单个bean
	//@Pointcut("within(com.jt.service..*)")  //按类匹配,控制的粒度较粗     多个bean
	@Pointcut("execution(* com.jt.service..*.*(..))") //细粒度的匹配方式
	public void pointCut() {
		
	}
	
	//joinPoint 方法执行切恰好被切入点表达式匹配,该方法的执行就称之为连接点.
	@Before("pointCut()")
	public void before(JoinPoint joinPoint) {
		System.out.println("我是前置通知!!!!");
		String typeName = 
				joinPoint.getSignature().getDeclaringTypeName();
		String methodName = joinPoint.getSignature().getName();
		Object[] objs = joinPoint.getArgs();
		Object target = joinPoint.getTarget();
		System.out.println("方法执行的全路径为:"+typeName+"."+methodName);
		System.out.println("获取方法参数:"+objs);
		System.out.println("获取目标对象:"+target);
	}
	
	
	//添加环绕通知  可以控制目标方法执行 要求添加参数
	@Around("pointCut()")
	public Object around(ProceedingJoinPoint joinPoint) {
		
		System.out.println("我是环绕通知开始");
		try {
			//Object result = joinPoint.proceed();
			System.out.println("我是环绕通知结束");
			return null;
		} catch (Throwable e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}  //指定目标方法
		
	}
	**/
}

9.1.8 redis分片实现

1 为什么使用分片
1).说明: 虽然redis可以扩展内存空间的大小.但是如果需要存储海量的数据一味的扩大内存,其实效率不高.
2).分片介绍: 准备多台redis,共同为用户提供缓存服务.在保证效率的前提下,实现了内存的扩容.
用户在使用分片机制时,将多台redis当做1台使用.

9.1.8.1分片搭建

由3台redis构成 端口号分别为6379/6380/6381, 如果需要准备多台redis则准备多个配置文件即可,注意其中的端口号.

准备多台redis

在这里插入图片描述
说明:修改redis的配置文件的端口号

在这里插入图片描述
启动多台redis
命令:

[root@localhost shards]# redis-server 6379.conf & redis-server 6380.conf & redis-server 6381.conf &

9.1.8.2redis持久化策略

RDB模式
特点:
1.rdb模式是redis中默认的持久化策略.
2.rdb模式定期持久化.保存的是Redis中的内存数据快照.持久化文件占用空间较小.
3.rdb模式可能导致内存数据丢失

命令:
前提:需要在redis的客户端中执行.

  1. save 命令 立即持久化 会导致其他操作陷入阻塞.
  2. bgsave 命令 开启后台运行. 以异步的方式进行持久化. 不会造成其他操作的阻塞.
save 900 1        900秒内,如果用户执行的1次更新操作,则持久化一次
save 300 10		  300秒内,如果用户执行的10次更新操作,则持久化一次
save 60 10000	  60秒内,如果用户执行的10000次更新操作,则持久化一次
save 1 1	 	  1秒内,如果用户执行的1次更新操作,则持久化一次    set 阻塞!!!!

在这里插入图片描述
在这里插入图片描述
AOF模式
特点:
1). AOF模式默认条件下是关闭状态. 如果需要开启则需要修改配置文件.
2). AOF模式可以实现数据的实时持久化操作,AOF模式记录的是用户的操作过程.
3). 只要开启了AOF模式,则持久化方式以AOF模式为主.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置多种持久化方式
1).设计 : 6379 当主机 7380当从机.
2).修改主机的配置文件:
要求: 主机使用RDB模式

在这里插入图片描述
从机使用AOF模式

在这里插入图片描述
检查默认模式的状态
命令: info replication

在这里插入图片描述
实现主从挂载
编辑从服务器向主机进行挂载

在这里插入图片描述

10.1 zookeeper下载安装

10.1.1安装

ZK下载
在这里插入图片描述
解压目录

tar -xvf zookeeper-3.4.8.tar.gz

10.1.2 配置文件修改

在zk根目录下创建文件夹data/log

在这里插入图片描述
跳入conf目录中修改配置文件
复制配置文件并且修改名称

cp zoo_sample.cfg zoo.cfg
在这里插入图片描述

10.1.3 启动ZK

跳转到bin目录中 zk启动关闭命令如下.

sh zkServer.sh start     或者  ./zkServer.sh start
sh zkServer.sh stop
sh zkServer.sh status

在这里插入图片描述

10.1.4 zookeeper集群安装

在zookeeper根目录中创建新的文件夹zkCluster.

在这里插入图片描述
创建zk1/zk2/zk3文件夹.

在这里插入图片描述
在每个文件夹里创建data/log文件夹.

命令

mkdir {zk1,zk2,zk3}/{data,log}
在这里插入图片描述

添加myid文件
分别在zk1/zk2/zk3中的data文件夹中创建新的文件myid.其中的内容依次为1/2/3,与zk节点号对应.

编辑配置文件
将zoo_sample.cfg 复制为zoo1.cfg之后修改配置文件.
在这里插入图片描述
修改zoo1.cfg文件
在这里插入图片描述
配置完成后将zoo1.cfg复制2份.之后需要修改对应的文件夹目录.和不同的端口即可.

10.1.5集群测试

通过下面的命令启动zk集群.

sh zkServer.sh start   zoo1.cfg
sh zkServer.sh stop    zoo1.cfg
sh zkServer.sh status  zoo1.cfg

检查主从关系

在这里插入图片描述
在这里插入图片描述
配置完成!!!

文件参考:
https://blog.csdn.net/qq_16804847/article/details/107504813

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值