# MySpringboot **Repository Path**: tml-tea/my-springboot ## Basic Information - **Project Name**: MySpringboot - **Description**: No description available - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-03-19 - **Last Updated**: 2024-05-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Springboot入门 ## 1、什么是SpringBoot 答:Springboot是pivotal团队开发的全新框架,是基于Spring基础上的一套解决方案,**作用是简化Spring项目的搭建和开发过程**。 ## 2、SSM不方便的地方 1、war包放到tomcat里面才能运行 2、配置文件不方便 3、导jar不方便 ## 3、为什么要学习SpringBoot? ### 1、独立运行 ​ SpringBoot内置各种Servlet容器,如Tomcat,Jetty等,使得应用可以打包成一个Jar包独立运行。 ### 2、自动配置 ​ Springboot能够自动配置Spring应用程序,**除了数据库以外,习惯优于配置**。 ### 3、简化开发 ​ Springboot集成了大量的第三方库配置,使得这些库在SpringBoot中可以零配置使用。 ## 4、SpringBoot配置文件的三种 1. application.properties 2. application.yaml 3. application.yml ## 5、常见的对象实体类型 Bean对象 数据库映射 VO对象 用于获取前端的请求数据和参数校验。 DTO 用于给前端响应数据,隐藏敏感内容。 ## 6、Springboot Jar包特性 ``` java -jar xxx.jar --server.port=8080 --其它参数 ``` 可以在启动jar包时临时替换配置参数 # Lombok插件 作用是用来生成set、get、构造函数、序列化等常见代码 1、导包 ```xml org.projectlombok lombok 1.18.24 ``` 2、下一个插件 ![image-20240305203524196](Springboot入门.assets/image-20240305203524196.png) # 工程的创建 ## NewProject Group: 公司域名反写 Artifact: 项目名(子父工程) Type: 项目构建方法 Language 开发语言 Packaging 打包方式 Java Version 开发版本 SpringBootVersion SpringBoot版本 Name:项目名(单纯项目名) Description:项目介绍 Package:包路径 java -jar 名称.jarr # 常用命令和快捷键 1. cd 跳转命令 2. dir 显示当前位置的内容 3. Ctrl + 鼠标左键进入对象 4. Ctrl + Q 返回 # 项目流程 **1、整理需求(产品经理)** 写PPT ------------------------------------------------------------项目部不能见甲方----------------------------------------------------- ---------------------------------------------------------甲方不直接和技术对接----------------------------------------------- **2、概要设计(项目经理)**写文档 **3、修Bug做项目架构 (技术经理 CTO)** 3、出效果图(UI设计) 4、详细设计 ... 5、写页面(前端工程师) **6、写接口,出接口文档(后端工程师)** --------------------------------------------------------------开发不能碰生产环境数据库----------------------------------------------------------------------------- --------------------------------------------------------------运维和实施不能碰代码----------------------------------------------------------------------------------- **7、项目部署(实施工程师)** **8、项目维护(运维工程师)** # knife4j 接口文档框架 ## 使用方式 ### 1、导包(springboot2) ```xml com.github.xiaoymin knife4j-openapi2-spring-boot-starter 4.4.0 ``` ### 2、配置接口文档 ```yaml # 接口文档配置 # Knife4j的配置开始 knife4j: enable: true # 启用Knife4j,true表示启用,false表示禁用 openapi: title: SpringBoot学习项目 # 设置OpenAPI文档的标题为"Knife4j官方文档" description: "`我是测试`,**你知道吗** # aaa" # 设置OpenAPI文档的描述。 email: 123@qq.com # 设置OpenAPI文档的联系人邮箱 concat: Z21软件后端开发团队 # 设置OpenAPI文档的附加信息为 url: https://docs.xiaominfo.com # 设置OpenAPI文档的URL为 version: v4.0 # 设置OpenAPI文档的版本为"v4.0" license: Apache 2.0 # 设置OpenAPI文档的许可为"Apache 2.0" license-url: https://stackoverflow.com/ # 设置许可的URL为 terms-of-service-url: https://stackoverflow.com/ # 设置服务条款的URL为 group: # 开始定义API分组 test1: # 第一个API分组名为"test1" group-name: 分组名称 # 设置该分组的名称为“分组名称” api-rule: package # 设置该分组的规则为“package”,通常表示根据包名进行API分组 api-rule-resources: # 设置满足上述规则的包路径列表 - com.example.demo.controller # 第一个包路径为 ``` ### 3、访问文档地址 **http://ip地址:端口号/doc.html** ### 4、常用注解 ``` @Api(tags = "登录接口") 用来标注Controller类 ``` ``` @ApiOperation(value = "用户名密码登录") 用来标注方法 ``` ``` @ApiModelProperty(value = "用户名",required = true) 用来标注字段 ``` # 异常拦截 拦截类上面加 @ControllerAdvice 拦截方法上面加 @ExceptionHandler(异常类.class) ## 参数校验 ```java @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class}) public ResponseEntity> handleValidatedException(Exception e) { Result result = null; if (e instanceof MethodArgumentNotValidException) { // 强制类型转换 MethodArgumentNotValidException ex =(MethodArgumentNotValidException) e; result = Result.error(86202,"参数校验异常", ex.getBindingResult().getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.toList()) ); } else if (e instanceof ConstraintViolationException){ ConstraintViolationException ex = (ConstraintViolationException) e; result = Result.error(86202,"参数校验异常", ex.getConstraintViolations().stream() .map(ConstraintViolation::getMessage) .collect(Collectors.toList()) ); }else if (e instanceof BindException) { BindException ex = (BindException ) e; result = Result.error(86202,"参数校验异常", ex.getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.toList()) ); } return new ResponseEntity<>(result,HttpStatus.BAD_REQUEST); } ``` # 用户注册 # 加密方式 ## 对称加密(私钥加密、共享密钥加密) 常见的算法有:DES、3DES、IDEA、RC4、RC5、RC6、AES等 公钥:公钥用于加密 私钥:私钥用于解密 ## 非对称加密 常见的算法有:RSA、ECC、DSA等 ## 不可逆加密(摘要加密) 常见算法: MD5、SHA系列等,这些算法可以将明文转化为固定长度的密文,但无法通过密文还原出明文,因此是不可逆的。 # 热部署 1、导包 ```xml org.springframework.boot spring-boot-devtools 3.2.0 ``` 2、配置项目的自动构建 ![image-20240312185209048](README.assets/image-20240312185209048.png) 3、Ctrl + Shift + Alt + / ![image-20240312185311177](README.assets/image-20240312185311177.png) 4、c-a-a-w-a-r 勾上 compiler.automake.allow.when.app.running 勾上 4、还有一地方 ![image-20240312185632686](README.assets/image-20240312185632686.png) # 项目的生命周期 ## 1、开发环境 dev 程序员自己的电脑 ## 2、测试环境 test 模拟的生产环境,用于上线前的测试 ## 3、生产环境 prod 就是线上有用户使用的环境 ## 语法规则 在springboot中我们可以创建 application-{环境名}.yml/properties文件来代表不同环境下的配置。 ![image-20240312192042049](README.assets/image-20240312192042049.png) 在主配置文件中使用active来切换不同的环境 ```yml spring: profiles: active: test # 当前整个项目的环境dev test prod ``` # Mybatis Plus逆向工程 添加操作 ```java //一个返回的是影响行数 getBaseMapper().insert(当前表的Entity); //一个返回的是当前数据的id this.save(当前表的Entity); ``` 简单的查询操作 ```java //查询条件 QueryWrapper 查询条件 = new QueryWrapper().eq("phone", usersInfo.getPhone()); //判断手机号是否存在 UsersInfo usersInfo1 = this.getOne(查询条件); //和上面是一样的,比上面长一点 getBaseMapper().selectOne(queryWrapper); ``` # Sa-Token ## 登录流程 在sa-token里保存用户的id ```java StpUtil.login(login.getUserId()); ``` ## 获取Token 底层使用的jwt的封装 ```java //获取当前会话的token String tokenValue = StpUtil.getTokenValue(); ``` ## 全局拦截器 ```java @Configuration public class SaTokenConfigure implements WebMvcConfigurer { // 注册 Sa-Token 拦截器,打开注解式鉴权功能 @Override public void addInterceptors(InterceptorRegistry registry) { // 注册 Sa-Token 拦截器,打开注解式鉴权功能 // 拦截所有请求/** registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); } } ``` ## 认证鉴权 ### 配置接口实现 ```java @Component public class StpInterfaceImpl implements StpInterface { @Autowired private IRoleService iRoleService; /** * 获取一个list作为权限认证 */ @Override public List getPermissionList(Object loginId, String loginType) { // 本 list 仅做模拟,实际项目中要根据具体业务逻辑来查询权限 List list = new ArrayList(); return list; } /** * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验) * loginId登录这个人的id */ @Override public List getRoleList(Object loginId, String loginType) { List strings = iRoleService.selectUserRoleById(Integer.parseInt(loginId.toString())); return strings; } } ``` ### 使用角色注解 ``` @SaCheckRole("角色") @SaCheckRole(value = {"角色1","角色2"},mode = SaMode.AND) @SaCheckRole(value = {"角色1","角色2"},mode = SaMode.OR) ``` ### 使用权限注解 **注解的key 一定是 模块.功能.功能** 如:user.update.age ``` @SaCheckPermission("tuition.update.money") 学费.修改.金额 ``` # WebSocket协议(长连接) 协议就是一种规范,USB接口(协议),Type-C接口(协议) WebSocket是基于TCP的一种**网络协议**,它实现了浏览器与服务器的全双工通信,浏览器和服务器只需要完成**一次握手**,两者之间就可以创建**持久**的连接,并进行**双向**通信。 ## HTTP和WebSocket协议的区别 HTTP是**短连接**而WebSocket是**长连接** HTTP是**单向的**而WebSocket是**双向的** ## 1代码实现-导包 ```xml org.springframework.boot spring-boot-starter-websocket ``` ## 2写服务端 ```java package com.example.demo.socket; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; /* * * @Author: Sjy * @Date: 2024/3/25-03-25-19:05 * 用于建立长连接的类 */ @Component //定义此类是WS的服务器端 @ServerEndpoint("/private/chat/{userId}") public class WebSocketServer { //ws一共有四种状态 /** * 连接建立成功时触发 * @param session 当前会话 */ @OnOpen public void onOpen(Session session){ System.out.println("我成功的建立了连接"); } /** * 连接关闭时触发 */ @OnClose public void onClose(){ } /** * 收到客户端消息时触发 * @param message */ @OnMessage public void onMessage(String message){ } /** * 发生错误时触发 * @param error */ @OnError public void onError(Throwable error){ } } ``` ## 3写客户端 ```javascript //专门用来写长连接 function loginSuccess(){ var userId = localStorage.getItem("userId"); //如果为空就不连 if(userId == null){ return; } //WebSocket对象 var ws = new WebSocket("ws://192.168.1.16:80/private/chat/"+userId); //连接成功时 ws.onopen = function(){ console.log("连接成功"); } //连接关闭时 ws.onclose = function(){ console.log("连接关闭"); setTimeout(()=>{ loginSuccess(); },2000); } //收到服务器的信息 ws.onmessage = function(e){ console.log(e); } //连接异常 ws.onerror = function(e){ console.log(e); } } //去触发长连接 loginSuccess(); ``` ## 4写配置类,注入WS ```java @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } } ``` ![image-20240326203344456](README.assets/image-20240326203344456.png) ## 5 注意事项 http:// 时使用 ws:// https:// 时使用 wss:// 更安全 # Redis ## 简介 Redis是(Remote Dictionarty Server)远程字典服务,是一个开源的**NoSQL数据库**,使用ANSI C语言编写的,它是一个**基于内存**的**Key-Value**数据库,并且支持**持久化**操作。 有丰富的数据结构如: 1. String (字符串) 2. Hash (可以理解为对象) 3. List (双向链表) 4. Set (string类型的无序集合) 5. Sorted Set (有序集合) ## SQL数据库 非关系型数据库,放弃了统一的技术标准(sql),为某一特定领域场景而设计,使性能、容量、扩展性都实现一定的突破。 特点 1. 不支持ACID 2. 不遵循SQL标准 3. 远超SQL性能 4. 海量数据读写 5. 高并发读写 常见NoSQL 1. mongoDB 高性能、开源、文档型数据库 2. HBase HBase支持数十亿行*数百万列的数据库表 是Hadoop项目的数据库 ## 语法 #### CLI的语法 ``` 方法一 redis-cli -h -p <端口号> -a <密码> 方法二 redis-cli -h -p <端口号> 进入以后输入 AUTH <密码> ``` key相关 ``` nil 的意思是无值或不存在,Go、Lua、Object-C 为空都是nil EX 20 设置键的过期时间是20秒 PX 3000 设置键的过期时间是3000毫秒 = 3秒 NX 如果键不存在则设置新的值,否则操作失败 XX 如果键已经存在就设置新的值,否则操作失败 NX和XX不能同时出现,因为他们语义互斥 ``` ``` 在key中可以使用:(冒号)来做单词分离,如:user:1 或 user:2 user称为命名空间 keys 后面加key的名字可以用*来做模糊查询 如:keys na*e:* del key 可以删除一个key或多个key (危险操作) exists key 查询key是否存在(0不存在 1存在) type key 可以返回这个key的类型 rename key newkey 给key进行重命名 expire key 秒 给指定key设置一个过期时间 pexpire key 毫秒 给指定的key设置一个毫秒过期时间 pexpireat key 时间戳 设置一个到达指定时间过期的key 用时间戳(如:1714741026000) ttl key 获取这个key的过期时间 如果为-1永不过期 如果-2没有这个key ``` ### 1、字符串语法 ``` set key value 设置一个值 get key 获取值 append key 在字符串后拼接字符串 getrange key start end 截取字符串从start(包前) end结束,end可以是固定位置也可以写-1 setnx key value 但key不存在时再设置key的值 strlen key 获取value的长度 ``` ### 2、Hash语法 Hash在Redis中是一个广泛使用的概念,主要是指一种任意长度的数据(如字符串)通过Hash算法变换成固定长度的数据格式的过程,这个固定长度的数据通常被称为哈希值或哈希码。 **Redis中每个hash可以存储2^32-1个键值对(40多亿)** ``` hset 对象名:对象id key value key value key value key value 设置一个对象 hget 对象名:对象id 属性key 查询单个属性 hgetall 对象名:对象id 查询所有属性 hdel 对象名:对象id 属性名 删除对应属性 hexists 对象名:对象id 属性名 检查属性是否存在,存在返回1,否则返回0 hmget 对象名:对象id 字段名1 字段名2 获取指定字段的值 ``` ### 3、List List在Redis中提供一种线性数据库结构,它可以存储一个字符串列表,按照插入顺序排序,可以中列表的两端推出或弹出元素。 主要特点:**元素有序**、**支持重复元素**、**可以通过索引访问元素**、**操作复杂度低**( 头部和尾部的时间复杂度为O(1) ) 常见八股文: 如何使用List实现一个消息队列? 如何遍历Redis的List? Redis的List最大存储多少个元素? 一个列表最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素) ![image-20240402205648750](README.assets/image-20240402205648750.png) ``` lpush key value value value value value 将一个或多个值插入到列表的头部 rpush 从右边(尾部)插入 rpop key 从右边(尾部)移除并获取一个元素 lpop key 从左边(头部)移除并获取一个元素 llen key 获取链表的长度 lrange key 0 -1 获取整个链表所有的数据 lindex key index 获取指定位置的元素的数据 ``` ### 4、Set Redis的Set数据结构能否能否重复? Redis集合最大存储?2^32-1 Set和List的区别? 使用场景:随机抽奖、唯一性检查 ``` sadd key value value 给set数据机构添加内容 smembers key 获取所有的元素 spop key 随机弹出并移除一个元素 ``` ### 5、sorted set 使用场景:实时排行榜系统,带权重的任务队列 ``` zadd vips 权重 值 权重 值 权重 值 添加数据到有序集合里 zrevrange key 0 -1 权重从大到小获取所有元素 加withscores和权重一起返回 zrange key 0 -1 权重从小到大排序 ``` ## 安装使用 https://redis.io/ ## SpringBoot整合Redis #### 导包 ```xml org.springframework.boot spring-boot-starter-data-redis io.lettuce lettuce-core 6.3.2.RELEASE ``` #### Lettuce特点: 1. **高性能** Lettuce通过使用NIO(非阻塞IO)和连接池等技术,实现了高性能的数据传输与链接管理 2. **异步和响应式** 单个线程中处理多个并发请求,提高的吞吐量 3. **可靠性** 自动重连故障转移 4. **可扩展性** 支持连接池和集群模式 #### 配置 ```java @Configuration public class RedisConfig { //配置序列化器 redisTemplate @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate redisTemplate=new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); //设置key的序列化器 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置value的序列化器 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } } ``` ```yaml spring: redis: host: 127.0.0.1 port: 6379 #password: database: 0 lettuce: pool: # 连接池 max-active: 8 #最大活跃数 max-wait: -1ms #但链接耗尽时,获取链接的最大等待时间 max-idle: 8 #最大空闲链接数 min-idle: 0 #最小空闲链接 ``` ![image-20240401185701197](README.assets/image-20240401185701197.png) ![image-20240401191300634](README.assets/image-20240401191300634.png) ![image-20240401204106638](README.assets/image-20240401204106638.png) ![image-20240408184141619](README.assets/image-20240408184141619.png) # 日志输出 ### 在类上添加注解 ``` @Slf4j ``` 使用 ```java //可以关 log.info("通过数据库查询"); //不能关 System.out.println("通过数据库查询"); ``` # 自定义注解 ## 什么是注解 注解就是一种标记 ## 创建注解 ```java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) //生命周期 @Component//被IOC注入到容器 public @interface AutoCustomAnnotation { } ``` ``` @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标) @Target(ElementType.TYPE) //接口、类 @Target(ElementType.FIELD) //属性 @Target(ElementType.METHOD) //方法 @Target(ElementType.PARAMETER) //方法参数 @Target(ElementType.CONSTRUCTOR) //构造函数 @Target(ElementType.LOCAL_VARIABLE) //局部变量 @Target(ElementType.ANNOTATION_TYPE) //注解 @Target(ElementType.PACKAGE) //包 ``` ```java RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期; RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在; ``` ## AOP + 注解 ### 什么是AOP 面向切面编程,通过切点表达式去对方法进行增强。 ### 如何找到自定义注解 ```java @Slf4j //日志注解 @Aspect //标记是一个aop切面 @Component //放到IOC容器 public class RedisCachingAspect { @Around("@annotation(com.example.demo.anno.AutoCustomAnnotation)")//可以写全路径 public Object cacheAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { log.info("我被执行了"); //放行 Object proceed = joinPoint.proceed(); return proceed; } } ``` # Quartz ## 什么是quartz? Quartz是一个任务调度框架,主要包括3个部分。 1. 任务(Job) : 需要实现的任务类,使用execute()方法 2. 触发器(Trigger):常用 SimpleTrigger和CronTrigger 3. 调度器(scheduler): 负责基于触发器来执行Job **任务是具体执行逻辑,触发器是执行时间和频率,调度器是规定任务绑定哪个触发器** ## 快速入门 ### 导包 ```xml org.springframework.boot spring-boot-starter-quartz ``` ### 配置yml ```yaml spring: quartz: # 存储类型 默认是内存 这里使用数据库存储 job-store-type: jdbc jdbc: # 是否初始化数据库: 总是初始化 initialize-schema: always ``` ### 任务(Job) **以job结尾 实现Job接口** ```java @Slf4j @Component public class CallMyGirlFriendsJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { //具体执行的内容 log.info("啊你嘎多美羊羊"); } } ``` ### 触发器(Trigger) ```java Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("girl", "call") //触发器的名称和分组 //cron 11点到12点,每5秒执行一次 .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * 11-12 * * ?")) .startNow() //立即触发 .build(); ``` ### 调度器(scheduler) ```java SchedulerFactory schedulerFactory = new StdSchedulerFactory(); // 获取调度器实例 Scheduler scheduler = schedulerFactory.getScheduler(); // JobDetail作业实例 JobBuilder 是哪个马楼被控制 JobDetail jobDetail = JobBuilder.newJob(CallMyGirlFriendsJob.class) .withIdentity("schedulerName", "schedulerGroup") .build();// 设置作业名称和组 // 创建一个触发器 Trigger trigger = SimpleGetTrigger.createTrigger(); // 添加作业和触发器 绑定 把马楼和上下班时间绑定 scheduler.scheduleJob(jobDetail, trigger); // 启动调度器 scheduler.start(); ``` # ECS云服务器 ## 如何找到服务器 ![image-20240416190547044](README.assets/image-20240416190547044.png) ![image-20240416190835178](README.assets/image-20240416190835178.png) ![image-20240416190953181](README.assets/image-20240416190953181.png) ## 如何修改密码 ![image-20240416191846206](README.assets/image-20240416191846206.png) ## 什么是公网ip ![image-20240416192023206](README.assets/image-20240416192023206.png) **局域网**:也叫内网ip地址 **公网ip**(public ip) 是指通过服务提供商(ISP)(移动、电信、联通)分配给用户的ip地址,通过公网ip可以被全球任何设备访问到。 ![image-20240416193319477](README.assets/image-20240416193319477.png) ### 什么是ip地址 ip地址是互联网设备的标识 = 人类的身份证,一台互联网设备可以有多个IP地址。 ## 域名 https://www.baidu.com/ 协议://主机名.域名 域名 约等于 公网ip地址的外号 ## 域名如何变成ip? 使用DNS服务器可以把域名解析成ip地址 ## DNS篡改攻击 是一种通过修改DNS设置,将用户域名转换成控制的恶意IP地址的一种方式。 ## 防火墙 防火墙在云服务厂家叫**安全组** ![image-20240416193950512](README.assets/image-20240416193950512.png) ![image-20240416194305361](README.assets/image-20240416194305361.png) # Linux操作系统 ## 什么是Linux操作系统? 是一个基于Linux内核的一种开源操作系统,提供了进程控制、进程通信、内存管理等功能。 ![87e62b1982a960e168a66b09f7bf396d](README.assets/87e62b1982a960e168a66b09f7bf396d.gif) ## Windows Server和Linux的区别 | Linux | Windows | 原因 | | ------ | -------------- | -------------- | | 开源 | 闭源 | | | 更安全 | 相比较不够安全 |Linux比Win有更良好的权限管理,开源社区不断更新和修复漏洞。 | | 更稳定 | 蓝屏 | | ## 如何连接Linux? 连接Linux需要SSH协议(22端口),全称叫Secure Shell,是一种在应用层上的安全协议,为远程登陆,文件传输提供安全性。 使用支持SSH的软件就可以连接到Linux 1. PuTTY 2. Xshell (教学用) 3. FinalShell 4. MobaXterm 5. 等 # Linux常用命令 ``` / 代表系统的根路径(最顶层目录) ~ 代表root目录 也叫主目录 d 如果以-开头代表是一个目录 - 如果以d开头代表的是一个文件 ``` 1. pwd 显示你当前再哪个目录下 2. exit 断开SSH连接 3. cd 切换到指定目录( .. 返回上一级 ~进入root目录 /切换到根目录) 4. ls -l 查看指定路径下的内容,不写查看当前 5. ll 和ls -l 一个意思 6. clear 清空当前屏幕 7. touch 名字.后缀 创建一个文件 8. mkdir 名字 创建一个文件夹 9. rm -rf 删除文件夹 10. mv /路径/文件名 /新路径 移动目录或文件 11. mv 目录名 目录名 给目录重命名 12. vim 文件名 编辑文件 按键盘的 i 开始编辑 (INSERT)可以编辑 按ESC 输入:wq回车 (w保存 q退出) :q! 强制退出不保存 (! 强制) :w! 强制保存 不退出 13. less 文件名 分页查看文档 q可以退出 j或回车 下一页 k或y 上一页 14. tar -zxvf 文件名 -C 解压路径 ``` 如 tar -zxvf jdk-8u411-linux-x64.tar.gz -C /usr/local/java/ ``` 14. wget 地址 下载地址 15. curl 工具 ``` curl http://127.0.0.1:81 发送get请求 curl http://www.baidu.com 发送get请求 curl -X POST http://域名 发送POST请求 ``` 16. find / -name 文件名 17. uname -a 查看当前操作系统名称,等基本信息 18. cat /etc/os-release 查看Linux发行版等系统信息 ​ ## Linux安装JDK 1. 把jdk-8u411-linux-x64.tar.gz通过XFTP上传到服务器 2. 在 /usr/local/java 路径创建目录 3. 回到jdk-8u411-linux-x64.tar.gz路径下 4. 解压jdk 到第2步的目录 5. 配置环境变量 /etc profile 文件 在最下面追加 ``` export JAVA_HOME=/usr/local/java/jdk1.8.0_411 export PATH=$PATH:$JAVA_HOME/bin ``` 6. 刷新环境变量 source /etc/profile 7. java -version ## Linux安装Mysql数据库 1. wget 下载mysql 2. 在 /usr/local/mysql 路径创建目录 3. 解压到这个目录 4. 到/usr/local/mysql/mysql5.7.9/bin路径下 5. 创建一个用户和用户组 ``` groupadd mysql useradd -r -g mysql mysql ``` 6. 把文件权限给mysql用户 ``` chown -R mysql:mysql /usr/local/mysql/mysql5.7.9 chown -R mysql:mysql /usr/local/mysql/data ``` 1. 初始化mysql 到bin路径 ``` ./mysqld --initialize --user=mysql --basedir=/usr/local/mysql/mysql5.7.9 --datadir=/usr/local/mysql/data ``` 6. 记住mysql临时密码 ``` root@localhost: 6svKaWfrPZ,u 如果报错执行 yum install libaio ``` 7.启动服务 配置文件 ``` vim /etc/my.cnf 加上 basedir=/usr/local/mysql datadir=/usr/local/mysql/data ``` ``` /usr/local/mysql/mysql5.7.9/support-fil ``` ``` ./mysql.server start ``` ## Linux安装mysql数据库RPM方式 在window中的exe可执行程序 > RPM 1、下载安装包 ![image-20240418103726199](README.assets/image-20240418103726199.png) 2.使用wgt下载下来 3.解压 ``` tar -xvf mysql-5.7.9-1.el7.x86_64.rpm-bundle.tar -C /root/mysql/mysqlrpm/ ``` ![image-20240418104500869](README.assets/image-20240418104500869.png) ``` client 客户端工具 mysql -u root -p需要的 common mysql的共享库文件 libs mysql所需的库文件 server 服务器安装包,数据库文件 ``` 4.卸载与mysql的冲突文件 ``` rpm -qa|grep mari 看有没有 有几个卸载几个 rpm -e --nodeps mariadb-libs 卸载 mariadb-libs是名字 ``` ![image-20240418104942713](README.assets/image-20240418104942713.png) 5.安装rpm ``` rpm -ivh 包名 ``` 6.安装顺序 ``` common > libs > server > client 如果在安装过程中报错 在 rpm -ivh 包名加 --force --nodeps ``` ![image-20240418105848049](README.assets/image-20240418105848049.png) 7.安装依赖 ``` yum -y install mariadb mariadb-devel mariadb-server ``` 8.设置目录权限 ``` 用户和用户组 groupadd mysql useradd -r -g mysql mysql ``` ``` chown mysql:mysql -R /var/lib/mysql ``` 9.启动服务 ``` systemctl start mysqld.service ``` 10.查看运行状态 ``` systemctl status mysqld.service ``` ![image-20240418112351911](README.assets/image-20240418112351911.png) 8.查看初始密码 ``` grep "password" /var/log/mysqld.log ``` ``` /var/log/mysqld.log ``` 9.如果没有初始密码 vim /etc/my.cnf文件 ![image-20240418115113850](README.assets/image-20240418115113850.png) **加上 skip-grant-tables** 保存退出后重启 ``` systemctl restart mysqld.service ``` 10.修改密码 ``` mysql -u root -p use mysql; update user set authentication_string=password('写你的密码') where user='root' and host='localhost'; 注意:密码一定要非常非常难 ``` ``` flush privileges; //刷新密码 ``` ``` 如果报1290 就先执行flush privileges; 刷新密码,再执行修改密码再刷新密码 ``` 11.退出保存 ``` exit 或者 quit 退出 取消 skip-grant-tables 空密码登录 重启服务 systemctl restart mysqld.service ``` 12.试一下刚才的密码 ``` mysql -u root -p 登录进去 登录的时候不显示密码 也不显示*号 盲写后直接回车 输入 show databases; ``` ## Mysql远程连接 ![image-20240423190040482](README.assets/image-20240423190040482.png) 1. 去阿里云 **安全组** 开放 入方向的3306端口 2. 打开navicat ![image-20240423190409177](README.assets/image-20240423190409177.png) ### 1130错误 如果报1130代表root账号不允许远程连接 ``` 进入数据库 mysql> use mysql; 百分号代表远程和本地都可以连接的意思 mysql> update user set host="%" where user = 'root'; 刷新配置 mysql> flush privileges; ``` 就可以远程连接了 ### 1820错误 **密码太简单,密码校验不通过,重新设置密码** ``` mysql -u root -p mysql> use mysql; mysql> update user set authentication_string=password('写你的密码') where user='root' and host='localhost'; 注意:密码一定要非常非常难 mysql> exit; systemctl restart mysqld.service 重启服务 ``` 第二张解决方案 ``` alter user 'root'@'localhost' identified by '密码'; ``` ## 修改Linux远程端口号22 ``` vim /etc/ssh/sshd_config ``` 把 #port:22放开并改成23或其他 ``` systemctl restart sshd 重启sshd服务 ``` 在安全组里面开放入方向的23端口 ## Linux隧道 ![image-20240418083956691](README.assets/image-20240418083956691.png) ## Java项目上线 ``` maven 执行package命令,在target目录下有个jar包 ``` 启动jar包 ``` java -jar 文件名.jar ``` ### 没有主配置文件 ``` 找不到启动类 ``` ![image-20240423205324182](README.assets/image-20240423205324182.png) ```xml org.springframework.boot spring-boot-maven-plugin 2.6.13 com.example.demo.DemoApplication ZIP repackage ``` ### 第二种方式 创建名为start.sh ``` nohup java -jar aaa.jar & ``` nohup ........ & 在后台运行进程 创建名为stop.sh ``` pkill -f "java -jar aaa.jar" ``` # Nginx ## 关键词:负载均衡、反向代理 ## 什么是Nginx? Nginx是一个高性能HTTP和反向代理Web服务器,同时提供了IMAP/POP3/SMTP服务。由俄罗斯访问量第二的Rambler.ru站点提供,作者:伊戈尔·塞索耶弗 ## 优势 作为Web服务器,和Apache Tomcat比,Nginx跟轻量占用资源少,并支持更多的并发连接。 ## 负载均衡 C语言开发的非常快,能作为HTTP代理服务器使用 ![image-20240424151652280](README.assets/image-20240424151652280.png) ### nginx.conf ```ini # 设置工作进程数为1。根据服务器配置,可调整为多进程以提升性能。 # 几核CPU对应几个进程 worker_processes 1; # 事件处理模块配置,设定每个工作进程的最大连接数。 events { worker_connections 1024; } # HTTP服务配置段 http { # 包含mime.types文件,用于自动识别并设置各种文件类型的Content-Type。 include mime.types; # 默认响应类型为二进制流。 default_type application/octet-stream; # 启用sendfile特性,用于高效发送文件。 sendfile on; # 设置TCP连接的保持活动状态超时时间。 keepalive_timeout 65; # 定义一个服务器块,监听端口80,适用于本地访问。 server { # 监听端口80,是HTTP服务的默认端口。 listen 80; # 服务器名称为localhost,可对应多个域名。 server_name localhost; # 配置根目录及默认索引文件。 location / { root html; # 设置文档根目录 index index.html index.htm; # 设置默认索引文件 } # 错误页面重定向配置。 error_page 500 502 503 504 /50x.html; # 指定错误页面地址 location = /50x.html { # 精确匹配错误页面地址 root html; # 错误页面所在目录 } } # 发布静态工程 server { listen 81; server_name www.taoshijituan.com; location / { root dist; index index.html index.htm; } } # 机器列表 upstream machine_list { ip_hash; #通过第一次分流 server 192.168.1.24:81 weight=5; #weight加权轮询 server 192.168.1.63:81 weight3; server 192.168.1.72:81 weight=1; } # 负载均衡 # http 80 # https 443 # 192.168.1.24 # 192.168.1.63 # 192.168.1.72 server { listen 82; location /aaa { proxy_pass http://machine_list; } location /bbb { proxy_pass http://machine_list; } location /ccc { proxy_pass http://machine_list; } } } ``` ### Nginx负载均衡策略 1. 轮询(Round Robin): 是Nginx默认策略,在轮询策略下,会按顺序调用,实现负载均衡 2. 加权轮询(Weighted Round Robin):是默认轮询的扩展,给服务器分配不同的权重,来决定请求发给哪台服务器,权重越高收到的请求越多。weight=权重 3. IP哈希(IP Hash) 通过请求的ip地址作为哈希建,确保同一地址的请求总是在一台服务器上 ip_hash 4. 最少连接(Least Connections): 分配当前请求到连接数最少的服务器上,确保服务器负载均衡,避某些服务器处理过多请求 5. URL哈希(URL Hash):通过URL地址作为Hash,确保相同URL在同一台服务器上(第三方插件) 6. 最短时间 (Least Time): 分配请求到响应最短时间的服务器上 (第三方) ## Linux安装nginx 找到官网 ``` https://nginx.org/en/download.html ``` ![image-20240424202658777](README.assets/image-20240424202658777.png) 并复制下载连接 ``` https://nginx.org/download/nginx-1.26.0.tar.gz ``` ``` mkdir /root/nginx cd /root/nginx wget https://nginx.org/download/nginx-1.26.0.tar.gz ``` 安装nginx的相关依赖 ``` yum install -y gcc pcre-devel openssl-devel zlib zlib-devel ``` 创建解压目录 ``` mkdir /usr/local/nginx ``` 解压 ``` tar -zxvf nginx-1.26.0.tar.gz -C /usr/local/nginx/ ``` 到解压目录 ``` cd /usr/local/nginx/ ./configure --prefix=/usr/local/nginx/ 编译 ``` 安装 ``` make make install ``` 验证 ``` systemctl status nginx 查看当前状态 systemctl stop nginx 停止 systemctl start nginx 启动 systemctl restart nginx 重启 running 代表运行成功 ``` ## Linux安装nginx 第二种 ``` sudo yum update #更新yum sudo yum install epel-release #获取依赖 sudo yum install nginx #安装nginx ``` ``` systemctl status nginx 查看当前状态 systemctl stop nginx 停止 systemctl start nginx 启动 systemctl restart nginx 重启 running 代表运行成功 ``` 和第一种比,区别是不能修改安装路径。安装的路径默认在 ``` /etc/nginx 路径下 ``` # Linux安装Redis 访问redis官网 ``` https://download.redis.io/releases/ ``` ``` cd ~ mkdir redis cd redis 下载 wget https://download.redis.io/releases/redis-7.2.4.tar.gz ``` 解压 ``` tar -zxvf redis-7.2.4.tar.gz ``` 安装 ``` make install ``` 切换目录 ``` cd /usr/local/bin ``` 后台启动 ``` nohup redis-server & ``` 验证 ``` redis-cli -h ip地址 -p 6379 ``` 找到解压路径 ``` cd /root/redis/redis-7.2.4 vim redis.conf ``` 注释 ``` #bind 127.0.0.1 注释调只允许自己连 ``` ``` 1045行 取消前面的#号 requirepass 密码 ``` 然后保存并退出 重启redis ``` ps -ef | grep redis-server 显示 root 10650 5289 0 09:73 画面 kill -9 10650 杀死进程 ``` 启动 ``` cd /usr/local/bin nohup redis-server /root/redis/redis-7.2.4/redis.conf & ``` ![image-20240425110824259](README.assets/image-20240425110824259.png) ``` redis-cli ping PONG 代表成功 ``` # 项目作品展架构图 ![image-20240425091132038](README.assets/image-20240425091132038.png) ![image-20240425091810243](README.assets/image-20240425091810243.png) # Git补充 ### 注意: 1. **创建分支时需要立即提交** 2. **修改分支内容后改其他分支之前需要提交** ``` git branch 分支名 创建分支 git branch 查询所有分支 git checkout 分支名 切换分支 git branch -d 分支名 删除本地分支 git branch -D 分支名 强制删除本地分支 git push origin --delete 分支名 删除远程仓库的分支 git merge 分支名 合并分支和主线 ``` # 云产品 ## 访问密钥 AccessKeyId 是阿里云的访问密钥Id AccessKeySecret 是阿里云的访问密钥密码 阿里云所有产品使用SDK调用时都使用AccessKey(访问密钥)来验证身份 ## OSS对象存储 ![image-20240507211540830](README.assets/image-20240507211540830.png) ### bucket(桶) 桶在OSS里面值的是存储空间,每个对象都需要隶属于一个空间,桶可以配置地域、访问权限、存储类型等。 ### 作业 5月8日 TODO6月份讲 完成垃圾回收任务 ![捕获](README.assets/捕获.PNG) 作业 5月9日 下载进度条,在下载文件时,给前端一个进度条,能看到实时下载过程。 作业 5月9日 图片合成接口完善 (见代码) # Docker 容器 ## 一、什么是容器 Docker是一个开源的容器化平台,它允许开发者将应用程序及所有依赖项打包到一个标准化的单元中,称为容器,每个容器都支持独立运行。 ## 二、Docker的核心概念 ### 1、镜像(Image) 镜像是容器的模板,用来构建容器,相当于java中的.class文件,它包含了应用程序及其所有依赖项,以及运行所需的环境配置 ### 2、容器(Container) 容器是Docker的运行实例,它是从镜像中创建的。每个容器都运行在独立的命名空间中,与其他容器**互相隔离** ### 3、仓库(Repository) 仓库是存放镜像的地址,类似于代码托管平台(GitHub、Gitee)上的仓库,Docker Hub是Docker官方提供的镜像仓库,开发者也可以搭建自己的仓库 ## 三、图解 ![捕获](README.assets/捕获-1715684273185.PNG) ![image-20240514193632010](README.assets/image-20240514193632010.png) ![image-20240514193920717](README.assets/image-20240514193920717.png) ![image-20240514194406470](README.assets/image-20240514194406470.png) ![image-20240514210939392](README.assets/image-20240514210939392.png) ![image-20240515204518233](README.assets/image-20240515204518233.png) ## 四、安装步骤 https://docs.docker.com/engine/install/ ![image-20240514191721477](README.assets/image-20240514191721477.png) https://docs.docker.com/engine/install/centos/ ![image-20240514191901015](README.assets/image-20240514191901015.png) ``` sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine ``` 卸载旧的Dokcer版本 ``` sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo ``` 下载安装docker的以来 ``` sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ``` 安装最新版本的docker ``` sudo systemctl start docker ``` 启动docker ``` sudo docker run hello-world ``` ## 五、配置容器加速 https://sme.aliyun.com/activity/huanxin?utm_content=se_1017005267&accounttraceid=3b70e7ebd8ff42cd85eee2b9b9c3d0bfvqvr ![image-20240514194742128](README.assets/image-20240514194742128.png) 进入管理控制台 ![image-20240514194843453](README.assets/image-20240514194843453.png) 找到加速器配置 ![image-20240514194933981](README.assets/image-20240514194933981.png) 找到加速命令并执行,每个人的都不样 ## 六、命令 ### docker version docker客户端和服务器的版本信息 ### docker info docker系统级信息,容器,镜像和驱动等信息 ### docker search <镜像名称> 搜索可用镜像 ### docker pull <镜像名>:<标签> 下载对应的镜像,标签也就是版本的意思 ### docker images 查看本地有哪些镜像 ### docker rmi <容器ID或镜像名称> 删除镜像,或使用docker image rm <容器ID或镜像名称> ### docker run <镜像名称>:<标签> 把镜像变成一个容器并启动它 还可以设置容器配置,如 ``` 如: docker run -d --name myname -it openjdk:8 ``` -p 设置端口映射 (如-p 6400:6379 宿主机的6400端口映射到容器的6379端口) -d 后台运行 --name 名字 -it 交互式运行(分配黑屏模式) -v 挂载路径 (可以挂载路径,也可以挂载文件) ### docker ps -a 查看若有容器(包括已停止的) ### docker rm <容器id或容器名称> 删除容器 ### docker start <容器id或容器名称> 启动容器 ### docker stop <容器id或容器名称> 停止容器 ### docker logs <容器id或容器名称> 查看容器日志 ### docker exec -it <容器id或容器名称>/bin/bash 进入容器 exit退出容器 ### docker cp docker cp <容器id或容器名称>:<容器内路径/文件名> <宿主机路径> 把容器内文件复制到宿主机 docker cp <宿主机路径> <容器id或容器名称>:<容器内路径/文件名> 把宿主机文件复制到指定容器内 如: ```yaml docker cp nginx:/etc/nginx/nginx.conf /root #把nginx容器内的nignx.conf文件复制到宿主机的/root目录下 docker cp /root/aaa/xxgc.jar myjava:/root/jar #把宿主机的/root/aaa/xxgc.jar包复制到 myjava容器下面的/root/jar路径下面 ``` ### 软件中的一些特性 #### 1、redis安装设置密码 ```yaml #示例命令 docker run -d -it --name redis --requirepass "你的密码" -p 6379:6379 redis # 安装redis时设置密码 --requirepass "你的密码" # 如果已经安装完成,需要进入容器,然后进入cli config set requirepass "你的密码" ``` #### 2、安装mysql5.7 ```yaml # 示例命令 docker run -d -it --name mysql57 -e MYSQL_ROOT_PASSWORD=<你的密码> -v /my/own/datadir:/var/lib/mysql -p 3306:3306 mysql:5.7 -v 挂载 宿主机路径:容器内路径 ``` #### 3、安装Nginx ```yaml # 示例命令 # 步骤1 启动一个不需要挂载的nginx docker run --name nginx -d -p 80:80 -p 443:443 nginx # 步骤2 把容器内需要挂载的文件 从容器内复制出来 docker cp nginx:/etc/nginx/nginx.conf /root/nginx # 步骤3 修改nginx.conf的内容 # 注释这个 # # include /etc/nginx/conf.d/*.conf; # 添加自己的配置 # 步骤4 停止并删除容器 # 步骤5 启动容器时挂载nginx.conf文件 docker run --name nginx -d -p 80:80 -p 443:443 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf nginx # 注意 nginx下面conf.d的目录,这个目录是可以将nginx的配置以模块的形式存放,并加载 # 这样每个项目都可以有一个单独的nginx配置文件 ``` ## 七、注意 1. Docker宿主机和容器间所有端口都是隔离的,但是可以做端口映射。 # 名词扩展 HR:人力资源主管 CTO:首席技术执行官 OPS:(Operations Per Second)每秒可以执行的运算次数(请求次数) QPS:(Queries Per Second) 每秒查询速率 端口: 值的是计算机与外部通信的出入口,范围是0~65535 这是B分支的笔记 # 快捷键 Ctrl + 鼠标左键 进入对象 Ctrl + Q 返回到上一级 Ctrl + E 最近打开过得文件 Ctrl + H 全局搜索(整个工程) Ctrl + F 文件内搜索 Ctrl + Shift + X 选中内容切换大小写 # HTTP常见状态码 200 成功 500 后端错误 404 资源未找到 405 不被允许的 HTTP 方法 (发的是Post但后端只写了@GetMapping),会在响应中列出了可用的方法 # 域名 域名备案需要3个月以上的服务器 ### HTTPS 申请一个ssl证书 1. 阿里云数字证书管理服务ssl 2. 左侧ssl证书 ![image-20240507195655514](README.assets/image-20240507195655514.png) 3. 1年可以0元买20个证书,每个证书只能使用3个月 ![image-20240507195837660](README.assets/image-20240507195837660.png) 4. 域名名称填写 比如 xyh.shijiayi.top 5. 勾上快捷签发 ![image-20240507200141839](README.assets/image-20240507200141839.png) ![image-20240507203358635](README.assets/image-20240507203358635.png)