首页
归档
友链
关于
Search
1
十年之约RSS聚合订阅服务上线
1,650 阅读
2
网易云音乐黑胶会员月月免费赠送
1,482 阅读
3
工资发放日的区别
1,067 阅读
4
rsyslogd内存占用过高解决方案
729 阅读
5
2022年中国移动A股成功上市,感恩有礼
627 阅读
零碎
标本
码海
工具
其他
登录
Search
标签搜索
摄影
旅行
北京
Java
Linux
教程
学习笔记
生活
SpringBoot
软件
服务器
Windows
系统
Spring
福利
南阳
服务
十堰
武汉
统信UOS
萧瑟
累计撰写
116
篇文章
累计收到
412
条评论
首页
栏目
零碎
标本
码海
工具
其他
页面
归档
友链
关于
搜索到
10
篇与
SpringBoot
的结果
2022-04-22
Nginx反代MinIO后,上传文件签名异常
很早之前自己搭建了一个MinIO对象存储服务,使用Nginx进行反代,但是使用SpringBoot对接的时候,上传文件总是报错。错误内容The request signature we calculated does not match the signature you provided. Check your key and signing method.错误内容大概是因为Nginx反代后请求签名与您提供的签名不匹配。Nginx配置文件我的配置文件server { listen 80; server_name minio.home.com; client_max_body_size 20M; #PROXY-START/ location / { proxy_pass http://127.0.0.1:9000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; add_header X-Cache $upstream_cache_status; # Set Nginx Cache add_header Cache-Control no-cache; expires 12h; } #PROXY-END/ }修改为官方的配置文件即可解决此问题server { listen 80; server_name minio.home.com; client_max_body_size 20M; #PROXY-START/ location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_connect_timeout 300; # Default is HTTP/1, keepalive is only enabled in HTTP/1.1 proxy_http_version 1.1; proxy_set_header Connection ""; chunked_transfer_encoding off; proxy_pass http://localhost:9000; # If you are using docker-compose this would be the hostname i.e. minio # Health Check endpoint might go here. See https://www.nginx.com/resources/wiki/modules/healthcheck/ # /minio/health/live; } #PROXY-END/ }参考文档setup-nginx-proxy-with-minio
2022年04月22日
50 阅读
2 评论
2022-03-01
[转载]SpringBoot项目优化和Jvm调优
项目调优作为一名工程师,项目调优这事,是必须得熟练掌握的事情。在SpringBoot项目中,调优主要通过配置文件和配置JVM的参数的方式进行。在这边有一篇比较好的文章,推荐给大家! SpringBoot项目配置Tomcat和JVM参数修改配置文件关于修改配置文件application.properties SpringBoot项目详细的配置文件修改文档 其中比较重要的有:server.tomcat.max-connections=0 # Maximum number of connections that the server accepts and processes at any given time. server.tomcat.max-http-header-size=0 # Maximum size, in bytes, of the HTTP message header. server.tomcat.max-http-post-size=0 # Maximum size, in bytes, of the HTTP post content. server.tomcat.max-threads=0 # Maximum number of worker threads. server.tomcat.min-spare-threads=0 # Minimum number of worker threads.Jvm调优关于Jvm调优Oracle官网有一份指导说明: Oracle官网对Jvm调优的说明 有兴趣大家可以去看看。Jvm调优实战未设置JVM参数的情况我现在有一个项目,默认情况下,没有设置任何Jvm参数。下面我来启动看一下。看一下堆栈分配:很明显默认的最大堆内存分配了8个G。很明显的不合理嘛。下面我们来设置下Jvm参数例如要配置JVM这么一大段参数:-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC方式一:如果你用的是IDEA等开发工具,来启动运行项目,那么要调试JDK就方便太多了。只需要将参数值设置到VM options中即可。设置成功,我的GC日志和堆栈分配都已经OK了。GC日志:堆栈分配:方式二:适用于在项目部署后,在启动的时候,采用脚本或者命令行运行的时候设置。先在项目路径下,给项目打包:清理就项目mvn clean打包新项目: mvn package -Dmaven.test.skip=true打包完成后进入可运行Jar包的路径下:执行启动设置Jvm参数的操作。$ java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC newframe-1.0.0.jar这个时候,你再看监控,你就会发现,已经是Ok的了。堆栈都是按照启动时候,设置的Jvm参数启动的。关于这些设置的JVM参数是什么意思,请参考第二步中的oracle官方给出的调优文档。我在这边简单说一下:-XX:MetaspaceSize=128m (元空间默认大小)-XX:MaxMetaspaceSize=128m (元空间最大大小)-Xms1024m (堆最大大小)-Xmx1024m (堆默认大小)-Xmn256m (新生代大小)-Xss256k (棧最大深度大小)-XX:SurvivorRatio=8 (新生代分区比例 8:2)-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)-XX:+PrintGCDetails (打印详细的GC日志)知识点:JDK8之后把-XX:PermSize 和 -XX:MaxPermGen移除了,取而代之的是-XX:MetaspaceSize=128m (元空间默认大小)-XX:MaxMetaspaceSize=128m (元空间最大大小)JDK 8开始把类的元数据放到本地化的堆内存(native heap)中,这一块区域就叫Metaspace,中文名叫元空间。使用本地化的内存有什么好处呢?最直接的表现就是java.lang.OutOfMemoryError: PermGen 空间问题将不复存在,因为默认的类的元数据分配只受本地内存大小的限制,也就是说本地内存剩余多少,理论上Metaspace就可以有多大(貌似容量还与操作系统的虚拟内存有关?这里不太清楚),这解决了空间不足的问题。不过,让Metaspace变得无限大显然是不现实的,因此我们也要限制Metaspace的大小:使用-XX:MaxMetaspaceSize参数来指定Metaspace区域的大小。JVM默认在运行时根据需要动态地设置MaxMetaspaceSize的大小。好啦,祝大家学习和工作顺利啦!文章原文: SpringBoot项目优化和Jvm调优
2022年03月01日
134 阅读
2 评论
2022-01-08
Java根据URL下载图片至客户端、服务器示例整合上传又拍云对象存储
Java根据URL下载图片至客户端、服务器示例整合又拍云上传
2022年01月08日
232 阅读
1 评论
2022-01-06
SpringBoot设置文件上传大小限制异常解决方案
SpringBoot默认上传文件大小超限,会报以下异常:org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.报错的原因是:springBoot项目自带的tomcat对上传的文件大小有默认的限制,SpringBoot官方文档中展示:每个文件的配置最大为1Mb,单次请求的文件的总数不能大于10Mb。解决方法:请在配置文件(application.properties/application.yml)中加入如下设置即可低版本: 1.Xspring.http.multipart.max-file-size=10MB spring.http.multipart.max-request-size=10MB高版本: 2.Xspring.servlet.multipart.max-file-size=30Mb spring.servlet.multipart.max-request-size=30Mb或者spring.servlet.multipart.maxFileSize=10MB spring.servlet.multipart.maxRequestSize=20MB
2022年01月06日
156 阅读
0 评论
2021-12-13
SpringBoot AOP日志切面
AOP切面AOP(Aspect-Oriented Programming,面向切面编程),它利用一种”横切”的技术,将那些多个类的共同行为封装到一个可重用的模块。便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。AOP相关概念Aspect(切面):声明类似于Java中的类声明,在Aspect中会包含一些Pointcut及相应的Advice。Joint point(连接点):表示在程序中明确定义的点。包括方法的调用、对类成员的访问等。Pointcut(切入点):表示一个组Joint point,如方法名、参数类型、返回类型等等。Advice(通知):Advice定义了在Pointcut里面定义的程序点具体要做的操作,它通过(before、around、after(return、throw)、finally来区别实在每个Joint point之前、之后还是执行 前后要调用的代码。Before:在执行方法前调用Advice,比如请求接口之前的登录验证。Around:在执行方法前后调用Advice,这是最常用的方法。After:在执行方法后调用Advice,after、return是方法正常返回后调用,afterthrow是方法抛出异常后调用。Finally:方法调用后执行Advice,无论是否抛出异常还是正常返回。AOP proxy:AOP proxy也是Java对象,是由AOP框架创建,用来完成上述动作,AOP对象通常可以通过JDK dynamic proxy完成,或者使用CGLIb完成。Weaving:实现上述切面编程的代码织入,可以在编译时刻,也可以在运行时刻,Spring和其它大多数Java框架都是在运行时刻生成代理。代码示例POM引入<!-- SpringBoot Aop组件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 分析客户端信息的工具类--> <dependency> <groupId>eu.bitwalker</groupId> <artifactId>UserAgentUtils</artifactId> <version>1.21</version> </dependency>切面:LogAspect代码/** * 添加aop日志打印 * * @author yanqs * @date 2020/1/13 14:42 */ @Aspect @Component @Slf4j public class LogAspect { /** * 进入方法时间戳 */ private Long startTime; /** * 方法结束时间戳(计时) */ private Long endTime; public LogAspect() { } /** * 定义请求日志切入点,其切入点表达式有多种匹配方式,这里是指定路径 */ @Pointcut("execution(public * com.springboot.logaop.controller.*.*(..))") public void logPointcut() { } /** * 前置通知: * 1. 在执行目标方法之前执行,比如请求接口之前的登录验证; * 2. 在前置通知中设置请求日志信息,如开始时间,请求参数,注解内容等 * * @param joinPoint * @throws Throwable */ @Before("logPointcut()") public void doBefore(JoinPoint joinPoint) { // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //获取请求头中的User-Agent UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); //打印请求的内容 startTime = System.currentTimeMillis(); log.info("请求开始时间:{}", LocalDateTime.now()); log.info("请求Url : {}", request.getRequestURL().toString()); log.info("请求方式 : {}", request.getMethod()); log.info("请求ip : {}", request.getRemoteAddr()); log.info("请求方法 : ", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("请求参数 : {}", Arrays.toString(joinPoint.getArgs())); // 系统信息 log.info("浏览器:{}", userAgent.getBrowser().toString()); log.info("浏览器版本:{}", userAgent.getBrowserVersion()); log.info("操作系统: {}", userAgent.getOperatingSystem().toString()); } /** * 返回通知: * 1. 在目标方法正常结束之后执行 * 1. 在返回通知中补充请求日志信息,如返回时间,方法耗时,返回值,并且保存日志信息 * * @param ret * @throws Throwable */ @AfterReturning(returning = "ret", pointcut = "logPointcut()") public void doAfterReturning(Object ret) throws Throwable { endTime = System.currentTimeMillis(); log.info("请求结束时间:{}", LocalDateTime.now()); log.info("请求耗时:{}", (endTime - startTime)); // 处理完请求,返回内容 log.info("请求返回 : {}", ret); } /** * 异常通知: * 1. 在目标方法非正常结束,发生异常或者抛出异常时执行 * 1. 在异常通知中设置异常信息,并将其保存 * * @param throwable */ @AfterThrowing(value = "logPointcut()", throwing = "throwable") public void doAfterThrowing(Throwable throwable) { // 保存异常日志记录 log.error("发生异常时间:{}", LocalDateTime.now()); log.error("抛出异常:{}", throwable.getMessage()); } }@Before和@AfterReturning部分也可使用以下代码替代/** * 在执行方法前后调用Advice,这是最常用的方法,相当于@Before和@AfterReturning全部做的事儿 * * @param pjp * @return * @throws Throwable */ @Around("logPointcut()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //获取请求头中的User-Agent UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); //打印请求的内容 startTime = System.currentTimeMillis(); log.info("请求Url : {}", request.getRequestURL().toString()); log.info("请求方式 : {}", request.getMethod()); log.info("请求ip : {}", request.getRemoteAddr()); log.info("请求方法 : ", pjp.getSignature().getDeclaringTypeName(), ".", pjp.getSignature().getName()); log.info("请求参数 : {}", Arrays.toString(pjp.getArgs())); // 系统信息 log.info("浏览器:{}", userAgent.getBrowser().toString()); log.info("浏览器版本:{}", userAgent.getBrowserVersion()); log.info("操作系统: {}", userAgent.getOperatingSystem().toString()); // pjp.proceed():当我们执行完切面代码之后,还有继续处理业务相关的代码。proceed()方法会继续执行业务代码,并且其返回值,就是业务处理完成之后的返回值。 Object ret = pjp.proceed(); log.info("请求结束时间:" + LocalDateTime.now()); log.info("请求耗时:{}", (System.currentTimeMillis() - startTime)); // 处理完请求,返回内容 log.info("请求返回 : ", ret); return ret; }测试结果2021-12-13 15:58:16.219 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求开始时间:2021-12-13T15:58:16.219 2021-12-13 15:58:16.220 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求Url : http://localhost:8080/test/getGetId 2021-12-13 15:58:16.220 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求方式 : GET 2021-12-13 15:58:16.220 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求ip : 0:0:0:0:0:0:0:1 2021-12-13 15:58:16.221 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求方法 : 2021-12-13 15:58:16.221 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求参数 : [zhangsan] 2021-12-13 15:58:16.221 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 浏览器:CHROME9 2021-12-13 15:58:16.221 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 浏览器版本:96.0.4664.55 2021-12-13 15:58:16.221 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 操作系统: WINDOWS_10 2021-12-13 15:58:16.229 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求结束时间:2021-12-13T15:58:16.229 2021-12-13 15:58:16.229 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求耗时:14 2021-12-13 15:58:16.229 INFO 21528 --- [nio-8080-exec-1] c.s.logaop.config.aspect.LogAspect : 请求返回 : zhangsanDemoSpringBoot-AOP参考:springboot配置aop切面日志打印 - 森林木马 - 博客园 springboot + AOP 日志_请叫我猿叔叔的博客-CSDN博客_aop日志
2021年12月13日
324 阅读
1 评论
2021-11-01
Spring Boot 核心知识点总结
Spring Boot 核心功能独立运行Spring项目 Spring boot 可以以jar包形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar来运行。内嵌servlet容器 Spring Boot可以选择内嵌Tomcat、jetty或者Undertow,这样我们无须以war包形式部署项目。提供starter简化Maven配置 spring提供了一系列的start pom来简化Maven的依赖加载,例如,当你使用了spring-boot-starter-web,会自动加入依赖包。自动装配Spring SpringBoot会根据在类路径中的jar包,类、为jar包里面的类自动配置Bean,这样会极大地减少我们要使用的配置。当然,SpringBoot只考虑大多数的开发场景,并不是所有的场景,若在实际开发中我们需要配置Bean,而SpringBoot灭有提供支持,则可以自定义自动配置。准生产的应用监控 SpringBoot提供基于http ssh telnet对运行时的项目进行监控。无代码生产和xml配置 SpringBoot不是借助与代码生成来实现的,而是通过条件注解来实现的,这是Spring4.x提供的新特性。Spring Boot 优缺点优点:快速构建项目。对主流开发框架的无配置集成。项目可独立运行,无须外部依赖Servlet容器。-提供运行时的应用监控。极大的提高了开发、部署效率。与云计算的天然集成。{dotted startColor="#ff6c6c" endColor="#1989fa"/}缺点:如果你不认同spring框架,也许这就是缺点。Spring Boot特性创建独立的Spring项目内置Tomcat和Jetty容器提供一个starter POMs来简化Maven配置提供了一系列大型项目中常见的非功能性特性,如安全、指标,健康检测、外部配置等完全没有代码生成和xml配置文件Spring Boot CLISpringBoot CLI 是SpringBoot提供的控制台命令工具。Spring Boot maven 构建项目spring-boot-starter-parent:是一个特殊Start,它用来提供相关的Maven依赖项,使用它之后,常用的包依赖可以省去version标签。Spring Boot几个常用的注解(1)@RestController和@Controller指定一个类,作为控制器的注解 ,并说明其区别(2)@RequestMapping方法级别的映射注解,这一个用过Spring MVC的小伙伴相信都很熟悉 (3)@EnableAutoConfiguration和@SpringBootApplication是类级别的注解,根据maven依赖的jar来自动猜测完成正确的spring的对应配置,只要引入了spring-boot-starter-web的依赖,默认会自动配置Spring MVC和tomcat容器(4)@Configuration类级别的注解,一般这个注解,我们用来标识main方法所在的类,完成元数据bean的初始化。(5)@ComponentScan类级别的注解,自动扫描加载所有的Spring组件包括Bean注入,一般用在main方法所在的类上 (6)@ImportResource类级别注解,当我们必须使用一个xml的配置时,使用@ImportResource和@Configuration来标识这个文件资源的类。 (7)@Autowired注解,一般结合@ComponentScan注解,来自动注入一个Service或Dao级别的Bean(8)@Component类级别注解,用来标识一个组件,比如我自定了一个filter,则需要此注解标识之后,Spring Boot才会正确识别。spring boot是如何管理事务的?直接写@transactional注解就行,在方法就是方法事务,类上就是类事务。
2021年11月01日
283 阅读
1 评论
2021-10-14
Java获取MultipartFile文件的MD5
Java 获取文件的 MD5 ,核心都是通过 Java 自带的 MessageDigest 类来实现。获取文件 MD5 值主要分为三个步骤,第一步获取文件的 byte 信息,第二步通过 MessageDigest 类进行 MD5 加密,第三步转换成16进制的 MD5 码值。方法一/** * 获取上传文件的md5 * @param file * @return * @throws IOException */ public String getMd5(MultipartFile file) { try { //获取文件的byte信息 byte[] uploadBytes = file.getBytes(); // 拿到一个MD5转换器 MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] digest = md5.digest(uploadBytes); //转换为16进制 return new BigInteger(1, digest).toString(16); } catch (Exception e) { log.error(e.getMessage()); } return null; }方法二使用 Java 自带的 commons-codec 包,获取16进制 MD5 值的方法。DigestUtils.md5Hex():提供三种类型( byte[] 、InputStream 、String )生成MD5/** * 获取上传文件的md5 * @param file * @return * @throws IOException */ public String getMd5(MultipartFile file) { try { byte[] uploadBytes = file.getBytes(); //file->byte[],生成md5 String md5Hex = DigestUtils.md5Hex(uploadBytes); //file->InputStream,生成md5 String md5Hex1 = DigestUtils.md5Hex(file.getInputStream()); //对字符串生成md5 String s = DigestUtils.md5Hex("字符串"); return md5Hex ; } catch (Exception e) { log.error(e.getMessage()); } return null; }
2021年10月14日
417 阅读
2 评论
2021-10-06
十年之约RSS聚合订阅服务上线
基于SpringBoot搭建的十年之约RSS聚合订阅服务正式上线,更多功能不定时更新。
2021年10月06日
1,650 阅读
26 评论
2021-07-04
Z-File – 开源免费的个人在线分享网盘
以前也曾使用过多个自建网盘的开源程序,比如 Cloudreve、NextCloud、Evoluted Directory Listing、SeaFile 等等。而最近我又发现了一个新的非常不错的开源网盘项目——Z-File。这是一个简单好用的个人网盘应用 (目录列表程序),可支持本地存储或对接各种对象存储服务……项目介绍此项目是一个在线文件目录的程序, 支持各种对象存储和本地存储, 使用定位是个人放常用工具下载, 或做公共的文件库. 不会向多账户方向开发.前端基于 h5ai 的原有功能使用 Vue 重新开发、后端采用 SpringBoot, 数据库采用内嵌数据库.官方预览地址:https://zfile.jun6.net/本站预览地址:https://pan.bcrjl.com/文档地址: http://docs.zhaojun.im/zfile项目特点Docker 支持文件数据库 (免安装)直链功能图片模式文件夹密码忽略文件夹自定义 JS, CSS自定义目录的 readme 说明文件支持在线浏览文本文件, 视频, 图片, 音乐. (支持 FLV 和 HLS)文件/目录二维码同时挂载多个存储策略缓存动态开启, 缓存自动刷新 (v2.2 及以前版本支持) 全局搜索 (v2.2 及以前版本支持) 支持 S3 协议, 阿里云 OSS, FTP, 华为云 OBS, 本地存储, MINIO, OneDrive 国际/家庭/个人版/世纪互联版/SharePoint, , 七牛云 KODO, 腾讯云 COS, 又拍云 USS.运行预览快速部署安装依赖环境:# CentOS系统 $ yum install -y java-1.8.0-openjdk unzip # Debian/Ubuntu系统 $ apt update $ apt install -y openjdk-8-jre-headless unzip如为更新程序, 则请先执行 rm -rf ~/zfile 清理旧程序. 首次安装请忽略此选项.下载项目$ wget -P ~ https://c.jun6.net/ZFILE/zfile-1.2.1.war $ cd ~ $ mkdir zfile && unzip zfile-1.2.1.war -d zfile && rm -rf zfile-1.2.1.war $ chmod +x ~/zfile/bin/*.sh下载指定版本可以将 zfile-release.war 改为 zfile-x.x.war,如 zfile-2.2.war。启动项目$ ~/zfile/bin/start.sh用户前台: http://127.0.0.1:8080/#/main初始安装: http://127.0.0.1:8080/#/install管理后台: http://127.0.0.1:8080/#/admin详细的安装教程及介绍请参考: ZFile 文档GitHub源代码{cloud title="Zfile前端" type="github" url="https://github.com/zhaojun1998/zfile-vue" password=""/}{cloud title="Zfile后端" type="github" url="https://github.com/zhaojun1998/zfile" password=""/}
2021年07月04日
161 阅读
0 评论
2021-05-23
SpringBoot yml配置文件注入List和Map
SpringBoot 在yml配置文件注入List和Map,可动态修改,方便快速。
2021年05月23日
135 阅读
0 评论