从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)

前言:

本章主要在原有项目上添加了日志配置,对SpringBoot默认的logback的配置进行了自定义修改,并详细阐述了xml文件配置要点(只对日志配置感兴趣的小伙伴可选择直接跳到第三节),并使用Feign代替原有RestTemplate完成微服务间调用,以及通过修改Feign的日志输出介绍了Feign配置的修改。

本章代码基于第4章项目,前置源码可在第4章博客下载,博客链接如下:

从零搭建微服务项目(第4章——Nacos环境隔离和配置拉取)-CSDN博客https://blog.csdn.net/wlf2030/article/details/145532798?sharetype=blogdetail&sharerId=145532798&sharerefer=PC&sharesource=wlf2030&spm=1011.2480.3001.8118简要介绍前置项目流程:order-service以及user-service两服务分别连接order-db以及user-db两数据库,order-db中仅有user-id,user-info存在user-db中,为提供完整order-info,order-service通过nacos发现user-service服务地址并使用RestTemplate调用其端口拿取user-info结合从order-db中拿取的信息返回给前端。

本项目源码链接如下:

wlf728050719/SpringCloudBase5https://github.com/wlf728050719/SpringCloudBase5以及本专栏会持续更新微服务项目,每一章的项目都会基于前一章项目进行功能的完善,欢迎小伙伴们关注!同时如果只是对单章感兴趣也不用从头看,只需下载前一章项目即可,每一章都会有前置项目准备部分,跟着操作就能实现上一章的最终效果,当然如果是一直跟着做可以直接跳过这一部分。


一、前置项目准备

1.从github下载前一章的项目解压,重命名为Base5打开。

2.重命名模块为Base5

3.父工程pom.xml中<name>改成Base5,

4.选择环境为dev,并重新加载maven

5.启动nacos(安装和启动见第三章)

6.进入nacos网页 配置管理->配置列表确认有这些yaml文件

(如果不是一直跟着专栏做自然是没有的,需要看第四章的环境隔离和配置拉取,记得把父工程pom文件中namespace的值与nacos中命名空间生成的保持一致)

7.配置数据源,更换两服务的resources下yml文件的数据库配置,数据库sql见第一章数据库准备部分。

.测试数据库连接 属性->点击数据源->测试连接->输入用户名密码

8.添加运行配置 服务->加号->运行配置类型->spring boot

启动服务

测试order-service

测试user-service


二、Feign基本使用

1.order-service的pom中添加feign依赖(建议使用下面release版本)

版本不对,可能会在启动order-service时出现如下报错,即找不到org.springframework.cloud.openfeign.FeignClientFactory的Bean

2.order-service的application开启feign客户端注解,并删除掉原有RestTemplate的bean

替换后内容如下:

package cn.bit.orderservice;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@MapperScan("cn.bit.orderservice.mapper")
@EnableFeignClients
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class, args);}
}

3.创建client接口

接口内容如下:能够看出feign即通过把url封装为接口方便调用,可以理解为每个FeignClient即对应一个微服务,但通过封装让业务看起来像是服务的内部调用。

package cn.bit.orderservice.client;import cn.bit.orderservice.bean.dto.UserBaseInfoDTO;
import cn.bit.orderservice.bean.vo.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/baseInfo/{id}")R<UserBaseInfoDTO> getUserBaseInfo(@PathVariable("id") Integer id);
}

4.更改order-service的serviceImpl实现

原有调用方式如下:(通过url调用服务)

替换后内容如下:(通过定义好的feignclient调用服务)

package cn.bit.orderservice.service.impl;import cn.bit.orderservice.bean.dto.UserBaseInfoDTO;
import cn.bit.orderservice.bean.po.OrderPO;
import cn.bit.orderservice.bean.vo.OrderInfoVO;
import cn.bit.orderservice.client.UserClient;
import cn.bit.orderservice.mapper.OrderMapper;
import cn.bit.orderservice.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;@Overridepublic OrderInfoVO getOrderInfoById(int orderId) {OrderPO orderPO = orderMapper.getOrderPOById(orderId);if (orderPO == null)return null;OrderInfoVO orderInfoVO = new OrderInfoVO();orderInfoVO.setOrderId(orderPO.getId());orderInfoVO.setAmount(orderPO.getAmount());orderInfoVO.setCreateTime(orderPO.getCreateTime());orderInfoVO.setGetLocation(orderPO.getGetLocation());try {// 获取买家信息UserBaseInfoDTO userBaseInfo1 = userClient.getUserBaseInfo(orderPO.getBuyerId()).getData();orderInfoVO.setBuyerName(userBaseInfo1.getUsername());// 获取卖家信息UserBaseInfoDTO userBaseInfo2 = userClient.getUserBaseInfo(orderPO.getSellerId()).getData();orderInfoVO.setSellerName(userBaseInfo2.getUsername());} catch (Exception e) {System.out.println("user-service connect error");e.printStackTrace();}return orderInfoVO;}
}

5.启动服务后测试

关闭user-service,无法获取用户信息且控制台有异常输出。


三、日志配置

为体现feign配置需要引入日志输出,之前的控制台的彩色输出是因为Spring Cloud默认日志实现是LogBack,其自动引入了对应的依赖,并有一套默认的配置。

如果需要自行配置日志格式,操作如下:

在order-service的resources目录下创建 logback-spring.xml文件,内容如下:

(本节最后有更完善的配置xml,本xm仅用于了解日志配置相关知识)

<?xml version="1.0" encoding="UTF-8"?>
<configuration><property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${LOG_PATTERN}</pattern></encoder></appender><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/order-service.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>logs/order-service.%d{yyyy-MM-dd}.log</fileNamePattern><maxHistory>30</maxHistory></rollingPolicy><encoder><pattern>${LOG_PATTERN}</pattern></encoder></appender><root level="info"><appender-ref ref="CONSOLE"/><appender-ref ref="FILE"/></root><logger name="cn.bit.orderservice" level="debug" additivity="false"><appender-ref ref="CONSOLE"/></logger>
</configuration>

其中LOG_PATTERN属性定义一种日志输出的格式

(1)appender name=console指定控制台输出采用哪种格式,此处采用上述定义的格式。

(2)appender name=file 指定日志文件记录的目录以及输出的格式。

(3)appender的name的命名随意,只要对应即可,关键实现是其后面的class属性决定了功能

(4)root level=info指定了根日志级别是info级别,除了所有被指定设置的logger其他所有日志级别在info及以上的都会执行console以及file,即控制台打印加日志文件记录。

(5)logger通过name指定cn.bit.orderservice包下日志级别为debug即以上的日志语句会打印在控制台。且设置其不会传播到父logger,其父logger为根,因此debug日志只会被控制台输出而不会被记录在日志文件中。

日志严重等级从高到低如下

        OFF:关闭所有日志记录。

        FATAL:记录严重错误事件,这些事件可能导致程序中断。

        ERROR:记录错误事件,但不会导致程序中断。

        WARN:记录潜在有害的情况。

        INFO:记录一般信息,用于描述程序运行过程中的关键事件。

        DEBUG:记录详细的调试信息,用于诊断问题。

        TRACE:记录最详细的调试信息,用于跟踪程序执行过程。

### 验证开始(该部分可自行选择跳过)

1.在order-service上添加上述xml文件,user-service不添加即使用默认配置

2.在order-controller的接口添加一句log的各种输出;会自动添加@Slf4j注解

3.启动服务,并调用一次接口,能够看到user-service的输出为彩色,order-service的输出为白色。说明每个模块用不同的配置(按照项目目前结构需要每个模块单独写log配置文件,后续有网关模块即可统一配置)

4.根目录有生成的logs目录和对应日志文件,验证上述(2)。

5.对比控制台输出和日志文件末尾,只有控制台记录了debug,info,warning,验证上述(4)(5)。

这时候肯定就有小伙伴有疑问,既然cn.bit.orderservice包已经被设定了只输出不记录为什么log文件里还有那么多记录。这时就会发现我着重加粗的是日志语句,不是从这个包输出的日志信息被单独配置了,而是这个包定义的日志语句被单独配置。这么说似乎还是有点抽象,下面来用案例说明。

用ctrl+左键跳转到这个HikariDataSource类,这是导入的类,不是项目编写的。

其构造函数中有logger的输出语句,也对应了上述的控制台输出

这时后在logback的配置文件为该类单独配置,即这个日志什么也不干。

然后删除刚才生成的log目录,再重新启动调用接口。前后对比就会发现上面的日志在控制台和文件中都不见了。

我个人的理解是,在编译时,编译器根据配置文件中特殊配置的logger,找到对应的类,扫描其所有logger,然后或面向切面或代理模式对这些logger进行功能增强,其他未特殊配置的类的logger就是默认的功能。不过只是个人理解,具体实现还得扒源码。

6.把logback.xml替换成下面内容, 即console变成console1,格式变成年月日,然后日志路径改成log12345

<?xml version="1.0" encoding="UTF-8"?>
<configuration><property name="LOG_PATTERN" value="%d{yyyy年MM月dd日 HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/><appender name="CONSOLE1" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${LOG_PATTERN}</pattern></encoder></appender><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs12345/order-service.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>logs/order-service.%d{yyyy-MM-dd}.log</fileNamePattern><maxHistory>30</maxHistory></rollingPolicy><encoder><pattern>${LOG_PATTERN}</pattern></encoder></appender><root level="info"><appender-ref ref="CONSOLE1"/><appender-ref ref="FILE"/></root><logger name="cn.bit.orderservice" level="debug" additivity="false"><appender-ref ref="CONSOLE1"/></logger><logger name="com.zaxxer.hikari.HikariDataSource" level="info" additivity="false"></logger>
</configuration>

7.启动后输出,验证上述(1)(2)(3)

### 验证结束

这时候会有人问,博主博主,你的日志xml讲解确实很多但还是太吃理解了,有没有更简单强势的xml推荐呢?

有的,兄弟!(bushi)

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"><property name="logLevel" value="INFO"/><property name="logPath" value="logs/order-service"/><property name="maxHistory" value="60"/><property name="queueSize" value="512"/><!-- 彩色日志格式 --><property name="CONSOLE_LOG_PATTERN"value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/><conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 控制台输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern></encoder></appender><!-- DEBUG 日志文件输出 --><appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${logPath}/debug.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${logPath}/debug-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>128MB</maxFileSize><maxHistory>${maxHistory}</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy><encoder><pattern>%date [%thread] %-5level [%logger{50}] - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- INFO 日志文件输出 --><appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${logPath}/info.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${logPath}/info-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>128MB</maxFileSize><maxHistory>${maxHistory}</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy><encoder><pattern>%date [%thread] %-5level [%logger{50}] - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- WARN 日志文件输出 --><appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${logPath}/warn.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${logPath}/warn-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>128MB</maxFileSize><maxHistory>${maxHistory}</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy><encoder><pattern>%date [%thread] %-5level [%logger{50}] - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- ERROR 日志文件输出 --><appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${logPath}/error.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${logPath}/error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern><maxFileSize>128MB</maxFileSize><maxHistory>${maxHistory}</maxHistory><totalSizeCap>10GB</totalSizeCap></rollingPolicy><encoder><pattern>%date [%thread] %-5level [%logger{50}] - %msg%n</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 异步日志记录 --><appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>${queueSize}</queueSize><neverBlock>true</neverBlock><appender-ref ref="FILE_DEBUG"/></appender><appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>${queueSize}</queueSize><neverBlock>true</neverBlock><appender-ref ref="FILE_INFO"/></appender><appender name="ASYNC_LOG_WARN" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>${queueSize}</queueSize><neverBlock>true</neverBlock><appender-ref ref="FILE_WARN"/></appender><appender name="ASYNC_LOG_ERROR" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>${queueSize}</queueSize><neverBlock>true</neverBlock><appender-ref ref="FILE_ERROR"/></appender><root level="${logLevel}"><appender-ref ref="STDOUT"/><appender-ref ref="ASYNC_LOG_DEBUG"/><appender-ref ref="ASYNC_LOG_INFO"/><appender-ref ref="ASYNC_LOG_WARN"/><appender-ref ref="ASYNC_LOG_ERROR"/></root><logger name="cn.bit.orderservice" level="debug" additivity="false"><appender-ref ref="STDOUT"/><appender-ref ref="ASYNC_LOG_DEBUG"/><appender-ref ref="ASYNC_LOG_INFO"/><appender-ref ref="ASYNC_LOG_WARN"/><appender-ref ref="ASYNC_LOG_ERROR"/></logger></configuration>

使用时只需要注意下面两点:

全局日志等级,这里设置为info,在没有特殊指定的情况下会把info及以上等级日志输出和输出到文件中。

单独配置项目文件即cn.bit.orderservice包中的日志,这里相等于把等级下调到了debug。

这些在控制台日志文件中就会有导入包的info及以上和项目中的debug及以上信息。

其实在nacos的yml或本地application.yml文件中也能使用logger.level对单独的包进行配置,但似乎并不能设置additivity属性阻止其传递给父logger.配置前缀如下:


四、Feign自定义配置

1.在order-service下创建配置类

类内容如下:(这里对feign的日志输出进行配置)

package cn.bit.orderservice.config;import org.springframework.context.annotation.Bean;
import feign.Logger;
public class FeignConfiguration {@Beanpublic Logger.Level feignLoggerLevel() {return Logger.Level.FULL;}
}

2.在order-service的application上启动配置(这种写法会使该模块下所有client都默认使用该配置)

或在UserClient上单独添加配置,具体如下:(因为后面会有多个client扩充,因此项目采用全局配置)

3.在前面日志配置好的情况下启动。

能够看到详细的feign信息。

换成basic

仅输出基本信息


最后:

很抱歉在第五章才加上日志配置的部分,这部分其实应该放在第0章,毕竟日志的重要性不言而喻。不过目前日志配置仍然是每个模块配置一个,实际在网关模块学习后只需要配置一个,并且能够通过使用@{project.artifactId}来使每个模块的日志输出到不同目录,目前仍然需要手动指定每个模块的输出路径。日志配置也会在后面的章节有所更改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/71444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【关于电商数据采集】电商数据采集的市场应用及发展

## 电商数据采集应用行业介绍 **一、 行业概述** 电商数据采集应用行业是指利用技术手段&#xff0c;自动或半自动地从电商平台、社交媒体等渠道获取商品信息、用户评论、销售数据等信息的行业。随着电子商务的蓬勃发展&#xff0c;数据已成为电商企业的重要资产&#xff0c;…

c++进阶———继承

1.引言 在一些大的项目中&#xff0c;我们可能要重复定义一些类&#xff0c;但是很麻烦&#xff0c;应该怎么办呢&#xff1f;举个简单的例子&#xff0c;我要做一个全校师生统计表&#xff0c;统计学号&#xff0c;教师编号&#xff0c;姓名&#xff0c;年龄&#xff0c;电话…

Golang学习笔记_34——组合模式

Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 Golang学习笔记_33——桥接模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 文件系统2. 图形界面3. 组织架构 四、代码示例&#xff08;Go语言&#xff09;五、…

【部署优化篇三】《DeepSeek边缘计算实战:把目标检测模型塞进树莓派,让AI在巴掌大的设备上“开天眼“》

“谁说只有超级计算机才能跑AI?今天咱们就要在树莓派上玩转DeepSeek目标检测,让这个巴掌大的小盒子变成会‘看’世界的智能终端!” 本文手把手教你从零开始,把最潮的目标检测模型塞进树莓派。全程高能预警,建议准备好你的树莓派4B/5和散热风扇,咱们这就开启边缘计算的魔法…

Django中数据库迁移命令

在 Django 中&#xff0c;数据库迁移是确保数据库结构与 Django 模型定义保持一致的重要过程。以下是 Django 中常用的数据库迁移命令&#xff1a; 1. python manage.py makemigrations 功能&#xff1a;此命令用于根据 Django 项目的模型文件&#xff08;models.py&#xff…

2023年河北省职业院校技能大赛网络系统管理赛项样题解法

​ 有问题请留言或主页私信咨询 配置文件有部分测试时的冗余配置无视即可。 解法只有大致解法&#xff0c;并不完整。请参考配置&#xff0c;自己补全 基础配置 1.所有交换机和无线控制器开启SSH服务&#xff0c;用户名密码分别为admin、admin1234&#xff1b;密码为明文类…

React之旅-02 创建项目

创建React项目&#xff0c;常用的方式有两种&#xff1a; 官方提供的脚手架&#xff0c;官网&#xff1a;https://create-react-app.dev/。如需创建名为 my-app 的项目&#xff0c;请运行如下命令&#xff1a; npx create-react-app my-app 使用Vite包&#xff0c;官网&…

Visual Studio Code的下载安装与汉化

1.下载安装 Visual Studio Code的下载安装十分简单&#xff0c;在本电脑的应用商店直接下载安装----注意这是社区版-----一般社区版就足够用了---另外注意更改安装地址 2.下载插件 重启后就是中文版本了

CAN总线常见的错误帧及产生原因

文章目录 一、位错误&#xff08;Bit Error&#xff09;1. 表现形式2. 产生原因 二、填充错误&#xff08;Stuff Error&#xff09;1. 表现形式2. 产生原因 三、CRC 错误&#xff08;CRC Error&#xff09;1. 表现形式2. 产生原因 四、格式错误&#xff08;Form Error&#xff…

在项目中调用本地Deepseek(接入本地Deepseek)

前言 之前发表的文章已经讲了如何本地部署Deepseek模型&#xff0c;并且如何给Deepseek模型投喂数据、搭建本地知识库&#xff0c;但大部分人不知道怎么应用&#xff0c;让自己的项目接入AI模型。 文末有彩蛋哦&#xff01;&#xff01;&#xff01; 要接入本地部署的deepsee…

【拥抱AI】GPT Researcher的诞生

一、GPT Researcher 研究过程总结 GPT Researcher 是一个开源的自主智能体&#xff0c;旨在通过利用人工智能技术实现高效、全面且客观的在线研究。它通过一系列创新的设计和优化&#xff0c;解决了传统研究工具&#xff08;如 AutoGPT&#xff09;中存在的问题&#xff0c;如…

52款独特婚礼主题手绘水彩花卉树叶高清png免抠图设计素材Floria – Botanical Elements

Floria 是一个独特的系列&#xff0c;由郁郁葱葱的植物元素组成&#xff0c;以绘画风格手绘。它们非常适合任何设计项目 – 包装、网站、博客、文具等等&#xff01; 在 Photoshop 中轻松更改颜色&#xff0c;并将其图层添加到任何纹理或颜色上。拥有 52 种花卉元素&#xff0c…

python入门笔记4

Python 中的列表&#xff08;List&#xff09;是 有序、可变 的序列类型&#xff0c;用方括号 [] 定义。以下是列表的核心语法和常用操作&#xff1a; list1 [Google, W3Cschool, 1997, 2000] list2 [7, 2, 3, 4, 5, 6, 1 ] #索引操作 print ("list1 first: ", li…

基于Ubuntu+vLLM+NVIDIA T4高效部署DeepSeek大模型实战指南

一、 前言&#xff1a;拥抱vLLM与T4显卡的强强联合 在探索人工智能的道路上&#xff0c;如何高效地部署和运行大型语言模型&#xff08;LLMs&#xff09;一直是一个核心挑战。尤其是当我们面对资源有限的环境时&#xff0c;这个问题变得更加突出。原始的DeepSeek-R1-32B模型虽…

Linux环境Docker使用代理推拉镜像

闲扯几句 不知不觉已经2月中了&#xff0c;1个半月忙得没写博客&#xff0c;这篇其实很早就想写了&#xff08;可追溯到Docker刚刚无法拉镜像的时候&#xff09;&#xff0c;由于工作和生活上的事比较多又在备考软考架构&#xff0c;拖了好久…… 简单记录下怎么做的&#xf…

撕碎QT面具(6):调节窗口大小后,控件被挤得重叠的解决方法

问题&#xff1a;控件重叠 分析原因&#xff1a;因为设置了最小大小&#xff0c;所以界面中的大小不会随窗口的变化而自动变化。 处理方案&#xff1a;修改mimumSize的宽度与高度为0&#xff0c;并设置sizePolicy为Expanding&#xff0c;让其自动伸缩。 结果展示&#xff08;自…

Mysql测试连接失败

解决方案 1 将mysql.exe(C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe)配置到系统环境变量 2 管理员权限启动cmd 输入 3 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 123456; 4 FLUSH PRIVILEGES;

【UCB CS 61B SP24】Lecture 3 - Lists 1: References, Recursion, and Lists学习笔记

本文开坑伯克利 CS 61B&#xff08;算法与数据结构&#xff09;2024年春季课程学习笔记&#xff0c;Lecture 1 & Lecture 2 的内容为课程介绍与 Java 基础&#xff0c;因此直接跳过。本文内容为介绍基本数据类型与引用数据类型的区别&#xff0c;以及手动实现整数列表。 1…

每日学习Java之一万个为什么

9.Class <?> class1 Myclass.class 为什么要有通配符&#xff1f;传给谁用的&#xff1f; 首先&#xff0c;这里的class特指某个对象在JVM中的元数据集合。 有普通、接口、数组、基本类型、 void 类型、局部类、匿名类、枚举、注解 1.类型安全&#xff1a;通配符允许…

【算法】787. 归并排序

题目 归并排序 思路 和快排一样&#xff0c;先判断数据是否没有或者只为一个&#xff1b;如果大于一个&#xff0c;取中间的值一分为二&#xff0c;然后两边递归&#xff0c;归并的实质是把两个有序数组排成一个&#xff0c;两个数组都从头开始比较&#xff0c;把更小的取下…