海量数据处理商用短链接生成器平台 - 4
第六章 架构核心技术-池化思想-异步结合 性能优化最佳实践
第1集 RestTemplate里面的存在的问题你知道多少- Broken pipe错误
项目就更新到第六章了,剩下的内容 放百度网盘里面了,需要的来取。
链接:https://pan.baidu.com/s/19LHPw36dsxPB75z_FHS64Q?pwd=8h89
提取码:8h89
简介: RestTemplate里面的存在的问题你知道多少
-
还原代码(暂时不用异步)
- 异步-里面是用线程池-是池化思想的一种应用
-
同步发送+resttemplate未池化
-
压测结果 几百吞吐量
-
错误Caused by: java.io.IOException: Broken pipe
- 服务端向前端socket连接管道写返回数据时 链接(pipe)却断开了
- 从应用角度分析,这是因为客户端等待返回超时了,主动断开了与服务端链接
- 连接数设置太小,并发量增加后,造成大量请求排队等待
- 网络延迟,是否有丢包
- 内存是否足够多支持对应的并发量
- 服务端向前端socket连接管道写返回数据时 链接(pipe)却断开了
-
-
问题分析
- resttemplate底层是怎样的?
- 基于之前的认知-池化思想,联想到是否使用了http连接池?
-
重新认识RestTemplate
- RestTemplate是Spring提供的用于访问Rest服务的客户端
- 底层通过使用java.net包下的实现创建HTTP 请求
- 通过使用ClientHttpRequestFactory指定不同的HTTP请求方式,主要提供了两种实现方式
- SimpleClientHttpRequestFactory(默认)
- 底层使用J2SE提供的方式,既java.net包提供的方式,创建底层的Http请求连接
- 主要createRequest 方法( 断点调试),每次都会创建一个新的连接,每次都创建连接会造成极大的资源浪费,而且若连接不能及时释放,会因为无法建立新的连接导致后面的请求阻塞
- HttpComponentsClientHttpRequestFactory
- 底层使用HttpClient访问远程的Http服务
- SimpleClientHttpRequestFactory(默认)
-
问题解决
- 客户端每次请求都要和服务端建立新的连接,即三次握手将会非常耗时
- 通过http连接池可以减少连接建立与释放的时间,提升http请求的性能
- Spring的restTemplate是对httpclient进行了封装, 而httpclient是支持池化机制
- 拓展
- 对httpclient进行封装的有:Apache的Fluent、es的restHighLevelClient、spring的restTemplate等
第2集 高性能RestTemplate连接池封装配置实战
简介: 高性能RestTemplate封装配置实战
- 配置RestTemplate连接池实战
@Beanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {return new RestTemplate(factory);}@Beanpublic ClientHttpRequestFactory httpRequestFactory() {return new HttpComponentsClientHttpRequestFactory(httpClient());}/*** @return*/@Beanpublic HttpClient httpClient() {Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", SSLConnectionSocketFactory.getSocketFactory()).build();PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);//设置整个连接池最大连接数connectionManager.setMaxTotal(500);//MaxPerRoute路由是对maxTotal的细分,每个主机的并发,这里route指的是域名connectionManager.setDefaultMaxPerRoute(200);RequestConfig requestConfig = RequestConfig.custom()//返回数据的超时时间.setSocketTimeout(20000)//连接上服务器的超时时间.setConnectTimeout(10000)//从连接池中获取连接的超时时间.setConnectionRequestTimeout(1000).build();return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();}
第3集 【10倍+QPS提升】Jmeter5.x压测 优化后RestTemplate前后性能对比
简介: 【10倍+提升】Jmeter5.x压测 优化后RestTemplate前后性能对比
-
同步发送+resttemplate未池化
- 压测结果 几百 吞吐量
-
同步发送+resttemplate池化
- 压测结果
-
检查你自己公司的项目,是否存在对应的问题
第七章 账号微服务-发送短信验证码-池化+异步结合最佳实践
第1集 调用第三方短信验证码组件性能优化实战
简介:调用第三方短信验证码组件性能优化实战
-
调整代码
-
采用异步调用方式
-
采用 resttemplate池化方式
第2集 说说一些薅羊毛的事情+防范解决方案
- 抢票
- 稀缺的酒、鞋等
-
短信邮箱轰炸机
- 什么是短信-邮箱轰炸机:
手机短信轰炸机是批量、循环给手机无限发送各种网站的注册验证码短信的方法。
- 美好的初衷-发明的由来
最早发明是用来整治街头广告电话号泛滥的一种手段,采用“手机短信轰炸机”软件可无限发送垃圾短信到牛皮癣小广告的手机号码上,使对方的手机快速消耗电量,变成高频率振动棒,且无法正常使用。“短信轰炸机”可严厉打击城市“牛皮癣”,还城市明净容颜。
- 灰色产业的目光-也就是部分不法分子利用
某次大型程序员相亲现场-老王得罪了小王, 小王不爽,就道听途说知道了”短信轰炸机“,1天50元,轰炸了5天还打折300元。一天内接到来自全国各地数千个陌生电话短信的轰炸骚扰,导致个人通讯中断,被工作生活受到严重影响,连刚相亲到的女友没没法联系上了。
-
原理
很多人都用手机注册一些网站的验证了,比如手机验证码。先填手机号,然后发一条验证码过去,输入验证码,完成验证,注册成功。* 寻找大量肉鸡网站,寻找发送验证码的请求接口* 如果找不到接口,也可以使用自动化UI工具触发* 编写程序和调度任务,相关脚本录入数据库* 输入目标手机号或者邮箱,触发攻击
-
公司带来的损失
- 短信一条5分钱,如果被大量盗刷大家自己计算
- 邮箱通知不用钱,但被大量盗刷,带宽、连接等都被占用,导致无法正常使用
-
如何避免自己的网站成为”肉鸡“或者被刷呢
- 增加图形验证码(开发人员)
- 单IP请求次数限制(开发人员)
- 限制号码发送(一般短信提供商会做)
-
是否可以一劳永逸???
-
没有百分百的安全,验证码是可以破解的,ip也是可以租用代理ip的
-
攻防永远是有的,只过加大了攻击者的成本,ROI划不过来自然就放弃了
-
第3集 图形验证码开发之谷歌kaptcha引入
简介:谷歌开源kaptcha图形验证码开发
-
Kaptcha 框架介绍 谷歌开源的一个可高度配置的实用验证码生成工具
- 验证码的字体/大小/颜色
- 验证码内容的范围(数字,字母,中文汉字!)
- 验证码图片的大小,边框,边框粗细,边框颜色
- 验证码的干扰线
- 验证码的样式(鱼眼样式、3D、普通模糊)
-
聚合工程依赖添加(使用国内baomidou二次封装的springboot整合starter)
<!--kaptcha依赖包--><dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId><version>1.1.0</version></dependency>
- 账号微服务添加
<dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId></dependency>
- 开发配置(任何框架和springboot整合基本都是)
@Configuration
public class CaptchaConfig {/*** 验证码配置* Kaptcha配置类名* * @return*/@Bean@Qualifier("captchaProducer")public DefaultKaptcha kaptcha() {DefaultKaptcha kaptcha = new DefaultKaptcha();Properties properties = new Properties();
// properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "220,220,220");
// //properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "38,29,12");
// properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "147");
// properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "34");
// properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "25");
// //properties.setProperty(Constants.KAPTCHA_SESSION_KEY, "code");//验证码个数properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Courier");//字体间隔properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8");//干扰线颜色
// properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "white");//干扰实现类properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");//图片样式properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.WaterRipple");//文字来源properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");Config config = new Config(properties);kaptcha.setConfig(config);return kaptcha;}
}
- 开发一个Controller使用测试
第4集 池化思想应用-Redis6.X配置连接池实战
简介:池化思想应用-Redis6.X配置连接池实战
-
连接池好处
- 使用连接池不用每次都走三次握手、每次都关闭Jedis
- 相对于直连,使用相对麻烦,在资源管理上需要很多参数来保证,规划不合理也会出现问题
- 如果pool已经分配了maxActive个jedis实例,则此时pool的状态就成exhausted了
-
连接池配置 common项目
<!--redis客户端--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>
-
配置Redis连接
redis:client-type: jedishost: 120.79.150.146password: class.netport: 6379jedis:pool:# 连接池最大连接数(使用负值表示没有限制)max-active: 100# 连接池中的最大空闲连接max-idle: 100# 连接池中的最小空闲连接min-idle: 100# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: 60000
-
序列化配置
@Configuration public class RedisTemplateConfiguration {/*** @param redisConnectionFactory* @return*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);// 使用Jackson2JsonRedisSerialize 替换默认序列化Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// 设置key和value的序列化规则redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// 设置hashKey和hashValue的序列化规则redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);return redisTemplate;} }
第5集 账号微服务开发图形验证码加入缓存+Try-with-resource
简介:账号微服务开发图形验证码接口+Try-with-resource
-
redis做隔离, 多集群:核心集群和非核心集群,高并发集群和非高并发集群
- 资源隔离
- 数据保护
- 提高性能
- key规范:业务划分,冒号隔离
- account-service:captcha:xxxx
- 长度不能过长
-
验证码接口开发
/***临时使用10分钟有效,方便测试*/private static final long CAPTCHA_CODE_EXPIRED = 60 * 1000 * 10;/*** 获取图形验证码* @param request* @param response*/@GetMapping("captcha")public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {String captchaText = captchaProducer.createText();log.info("图形验证码:{}", captchaText);//存储redisTemplate.opsForValue().set(getCaptchaKey(request),captchaText, CAPTCHA_CODE_EXPIRED, TimeUnit.MILLISECONDS);BufferedImage bufferedImage = captchaProducer.createImage(captchaText);try (ServletOutputStream outputStream = response.getOutputStream()){ImageIO.write(bufferedImage, "jpg", outputStream);outputStream.flush();} catch (IOException e) {log.error("获取图形验证码异常:{}", e);}}
- 什么是try-with-resources
- 资源的关闭很多⼈停留在旧的流程上,jdk7新特性就有, 但是很多⼈以为是jdk8的
- 在try( …)⾥声 明的资源,会在try-catch代码块结束后⾃动关闭掉
- 注意点
- 实现了AutoCloseable接⼝的类,在try()⾥声明该类实例的时候,try结束后⾃动调⽤的 close⽅法,这个动作会早于finally⾥调⽤的⽅法
- 不管是否出现异常,try()⾥的实例都会被调⽤close⽅法
- try⾥⾯可以声明多个⾃动关闭的对象,越早声明的对象,会越晚被close掉
第6集 账号微服务之注册短信验证码接口开发
简介:注册短信验证码接口开发
- service层
@Overridepublic JsonData sendCode(SendCodeEnum sendCodeType, String to) {if(CheckUtil.isEmail(to)){//邮箱验证码}else if(CheckUtil.isPhone(to)){//短信验证码}return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);}
- 邮箱工具类正则
public class CheckUtil {/*** 邮箱正则*/private static final Pattern MAIL_PATTERN = Pattern.compile("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");/*** 手机号正则*/private static final Pattern PHONE_PATTERN = Pattern.compile("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$");/*** @param email* @return*/public static boolean isEmail(String email) {if (null == email || "".equals(email)) {return false;}Matcher m = MAIL_PATTERN.matcher(email);return m.matches();}/*** * @param phone* @return*/public static boolean isPhone(String phone) {if (null == phone || "".equals(phone)) {return false;}Matcher m = PHONE_PATTERN.matcher(phone);boolean result = m.matches();return result;}
}
第7集 关于注册短信验证码防刷设计方案你能想到几个
简介:注册短信验证码防刷方案你能想到几个
-
需求:一定时间内禁止重复发送短信,大家想下有哪几种实现方式
- 两个时间要求
- 60秒后才可以重新发送短信验证码
- 发送的短信验证码10分钟内有效
- 两个时间要求
-
-
方式一:前端增加校验倒计时,不到60秒按钮不给点击
- 简单
- 不安全,存在绕过的情况
-
方式二:增加Redis存储,发送的时候设置下额外的key,并且60秒后过期
-
非原子操作,存在不一致性
-
增加的额外的key - value存储,浪费空间
-
/*** 前置:判断是否重复发送** 1、存储验证码到缓存** 2、发送短信验证码** 后置:存储发送记录**/
-
-
方式三:基于原先的key拼装时间戳
- 好处:满足了当前节点内的原子性,也满足业务需求
-
第8集 【重要】注册邮箱验证码防刷代码落地+整体测试
简介:注册邮箱验证码防刷落地和整体测试
@Overridepublic JsonData sendCode(SendCodeEnum sendCodeEnum, String to) {String cacheKey = String.format(RedisKey.CHECK_CODE_KEY,sendCodeEnum.name(),to);String cacheValue = redisTemplate.opsForValue().get(cacheKey);//如果不为空,再判断是否是60秒内重复发送 0122_232131321314132if(StringUtils.isNotBlank(cacheValue)){long ttl = Long.parseLong(cacheValue.split("_")[1]);//当前时间戳-验证码发送的时间戳,如果小于60秒,则不给重复发送long leftTime = CommonUtil.getCurrentTimestamp() - ttl;if( leftTime < (1000*60)){log.info("重复发送短信验证码,时间间隔:{}秒",leftTime);return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);}}String code = CommonUtil.getRandomCode(6);//生成拼接好验证码String value = code+"_"+CommonUtil.getCurrentTimestamp();redisTemplate.opsForValue().set(cacheKey,value,CODE_EXPIRED,TimeUnit.MILLISECONDS);if(CheckUtil.isEmail(to)){//发送邮箱验证码 TODO}else if(CheckUtil.isPhone(to)){//发送手机验证码smsComponent.send(to,smsConfig.getTemplateId(),code);}return JsonData.buildSuccess();}
第八章 账号微服务-阿里云OSS接入实战
第1集 分布式文件存储业界常见解决方案介绍
简介:分布式文件存储常见解决方案介绍
-
目前业界比较多这个解决方案,这边就挑选几个介绍下
- MinIO
是在 Apache License v2.0 下发布的对象存储服务器,学习成本低,安装运维简单,主流语言的客户端整合都有, 号称最强的对象存储文件服务器,且可以和容器化技术docker/k8s等结合,社区活跃但不够成熟,业界参考资料较少官网:https://docs.min.io/cn/
- FastDFS
一个开源的轻量级分布式文件系统,比较少的客户端可以整合,目前主要是C和java客户端,在一些互联网创业公司中有应用比较多,没有官方文档,社区不怎么活跃. 架构+部署结构复杂,出问题定位比较难定位,可以说是fastdfs零件的组装过程,需要去理解fastDFS的架构设计,才能够正确的安装部署
-
云厂商
-
阿里云OSS
-
七牛云
-
腾讯云
-
亚马逊云
-
CDN最强:Akamai https://www.akamai.com/cn
-
-
选云厂商理由
- 优点:开发简单,功能强大,容易维护(不同网络下图片质量、水印、加密策略、扩容、加速)
- 缺点:要钱, 个性化处理,未来转移比较复杂,不排除有些厂商会提供一键迁移工具
-
选开源MinIO的理由
- 优点:功能强大、可以根据业务做二次的定制,新一代分布式文件存储系统,容器化结合强大,更重要的是免费(购买磁盘、内存、带宽)
- 缺点:自己需要有专门的团队进行维护、扩容等
-
文件上传流程
- web控制台
- 前端->后端程序->阿里云OSS
第2集 阿里云OSS分布式对象存储介绍开通
简介:阿里云OSS对象存储介绍和开通
- 阿里云OSS介绍
对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务设计可用性不低于99.995%。OSS具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。提供标准、低频访问、归档和冷归档四种存储类型,全面覆盖从热到冷的各种数据存储场景:
标准存储类型 | 高持久、高可用、高性能的对象存储服务,支持频繁的数据访问。是各种社交、分享类的图片、音视频应用、大型网站、大数据分析的合适选择。 |
---|---|
低频访问存储类型 | 适合长期保存不经常访问的数据(平均每月访问频率1到2次)。存储单价低于标准类型,适合各类移动应用、智能设备、企业数据的长期备份,支持实时数据访问。 |
归档存储类型 | 适合需要长期保存(建议半年以上)的归档数据,在存储周期内极少被访问,数据进入到可读取状态需要1分钟的解冻时间。适合需要长期保存的档案数据、医疗影像、科学资料、影视素材。 |
冷归档存储类型 | 适合需要超长时间存放的极冷数据。例如因合规要求需要长期留存的数据、大数据及人工智能领域长期积累的原始数据、影视行业长期留存的媒体资源、在线教育行业的归档视频等。 |
-
开通阿里云OSS
-
有阿里云账号、实名认证
-
OSS介绍:https://www.aliyun.com/product/oss
-
OSS控制台:https://oss.console.aliyun.com/bucket
-
学习路径:https://help.aliyun.com/learn/learningpath/oss.html
-
-
开通后的操作
- 创建Bucket
- 上传文件
- 访问文件
第3集 权限知识 RBAC-ACL模式应用之阿里云RAM访问控制
简介:权限知识 RBAC-ACL模式应用之阿里云RAM访问控制
-
ACL: Access Control List 访问控制列表
- 以前盛行的一种权限设计,它的核心在于用户直接和权限挂钩
- 优点:简单易用,开发便捷
- 缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理
- 例子:常见的文件系统权限设计, 直接给用户加权限
-
RBAC: Role Based Access Control
- 基于角色的访问控制系统。权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限
- 优点:简化了用户与权限的管理,通过对用户进行分类,使得角色与权限关联起来
- 缺点:开发对比ACL相对复杂
- 例子:基于RBAC模型的权限验证框架与应用 Apache Shiro、spring Security
-
总结:不能过于复杂,规则过多,维护性和性能会下降, 更多分类 ABAC、PBAC等
-
RAM权限介绍
-
阿里云用于各个产品的权限,基于RBAC、ACL模型都有,进行简单管理账号、统一分配权限、集中管控资源,从而建立安全、完善的资源控制体系。
-
众多产品,一般采用子账号进行分配权限,防止越权攻击
-
建立用户,勾选编程访问(保存accessKey和accessSecret,只出现一次)
- 用户登录名称 dcloud_link@1701673122790560.onaliyun.com AccessKey ID : LTAI5tHVGvYw7twoVFyruB1H AccessKey Secret : r4d0EudzSvPfVMb9Zp0TfmsE32RXmN
-
为新建用户授权OSS全部权限
-
第4集 阿里云OSS客户端SDK集成和上传组件功能开发
简介:阿里云OSS对象存储客户端集成和测试服务
-
添加阿里云OSS的SDK
-
地址:https://help.aliyun.com/document_detail/32008.html
-
添加maven依赖
- 底层聚合工程添加版本
<!-- OSS各个项目单独加依赖,根据需要进行添加--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.10.2</version></dependency>
- 账号微服务添加
<!-- OSS各个项目单独加依赖,根据需要进行添加--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId></dependency>
-
-
账号微服务配置OSS
#阿里云OSS配置
aliyun:oss:endpoint: oss-cn-guangzhou.aliyuncs.comaccess-key-id: LTAI5tHVGvYw7twoVFyruB1Haccess-key-secret: r4d0EudzSvPfVMb9Zp0TfmsE32RXmNbucketname: dcloud-link
- 新建配置类 (配置里面的横杠会,自动转驼峰)
@ConfigurationProperties(prefix = "aliyun.oss")
@Configuration
@Data
public class OSSConfig {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketname;
}
-
开发controller
-
开发service
@Service
@Slf4j
public class FileServiceImpl implements FileService {@Autowiredprivate OSSConfig ossConfig;@Overridepublic String uploadUserImg(MultipartFile file) {//获取相关配置String bucketname = ossConfig.getBucketname();String endpoint = ossConfig.getEndpoint();String accessKeyId = ossConfig.getAccessKeyId();String accessKeySecret = ossConfig.getAccessKeySecret();//创建OSS对象OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);//获取原生文件名 xxx.jpgString originalFileName = file.getOriginalFilename();//JDK8的日期格式LocalDateTime ldt = LocalDateTime.now();DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");//拼装路径,oss上存储的路径 user/2022/12/1/sdfdsafsdfdsf.jpgString folder = dtf.format(ldt);String fileName = CommonUtil.generateUUID();String extension = originalFileName.substring(originalFileName.lastIndexOf("."));// 在OSS上的bucket下创建 user 这个文件夹String newFileName = "user/"+folder+"/"+fileName+ extension;try {PutObjectResult putObjectResult = ossClient.putObject(bucketname,newFileName,file.getInputStream());//拼装返回路径if(putObjectResult != null){String imgUrl = "https://"+bucketname+"."+endpoint+"/"+newFileName;return imgUrl;}} catch (IOException e) {log.error("文件上传失败:{}",e);} finally {//oss关闭服务,不然会造成OOMossClient.shutdown();}return null;}
}
第5集 账号微服务头像上传阿里云OSS接口和PostMan测试
简介: 账号微服务头像上传阿里云OSS接口和PostMan测试
- 文件上传流程
- 先上传文件,返回url地址,再和普通表单一并提交(推荐这种,更加灵活,失败率低)
- 文件和普通表单一并提交(设计流程比较多,容易超时和失败)
- 注意:默认SpringBoot最大文件上传是1M,大家测试的时候记得关注下
- 开发controller
- @requestPart注解 接收文件以及其他更为复杂的数据类型
/*** 上传用户头像** 默认文件大小 1M,超过会报错** @param file* @return*/@PostMapping(value = "upload")public JsonData uploadHeaderImg(@RequestPart("file") MultipartFile file){String result = fileService.uploadUserHeadImg(file);return result != null?JsonData.buildSuccess(result):JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL);}
} catch (IOException e) {log.error("文件上传失败:{}",e);} finally {//oss关闭服务,不然会造成OOMossClient.shutdown();}return null;
}
}
#### 第5集 账号微服务头像上传阿里云OSS接口和PostMan测试**简介: 账号微服务头像上传阿里云OSS接口和PostMan测试**- 文件上传流程- 先上传文件,返回url地址,再和普通表单一并提交(推荐这种,更加灵活,失败率低)- 文件和普通表单一并提交(设计流程比较多,容易超时和失败)
- 注意:默认SpringBoot最大文件上传是1M,大家测试的时候记得关注下
- 开发controller- @requestPart注解 接收文件以及其他更为复杂的数据类型```java/*** 上传用户头像** 默认文件大小 1M,超过会报错** @param file* @return*/@PostMapping(value = "upload")public JsonData uploadHeaderImg(@RequestPart("file") MultipartFile file){String result = fileService.uploadUserHeadImg(file);return result != null?JsonData.buildSuccess(result):JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL);}
相关文章:

海量数据处理商用短链接生成器平台 - 4
第六章 架构核心技术-池化思想-异步结合 性能优化最佳实践 第1集 RestTemplate里面的存在的问题你知道多少- Broken pipe错误 项目就更新到第六章了,剩下的内容 放百度网盘里面了,需要的来取。 链接:https://pan.baidu.com/s/19LHPw36dsxPB7…...

基于CNN+LSTM深度学习网络的时间序列预测matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 卷积神经网络(CNN) 4.2 长短时记忆网络(LSTM) 4.3 CNNLSTM网络结构 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MA…...

如何控制系统安全 或 控制流氓软件
电脑 出入数据的地方是安全保障的最后一关 比如 网络 , usb 等等 控制联网流氓软件 1 在虚拟机里测试软件是否有恶意行为 恶意行为非常容易发现 比如 破坏文件 修改文件 系统不正常 像蓝屏 等等 2 网络防火墙 这是系统最关键的部分之一 像 windows 一定使用他…...

【Docker】Docker Container(容器)
文章目录 一、什么是容器?二、为什么需要容器?三、容器的生命周期容器OOM容器异常退出容器暂停 四、容器命令详解docker createdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker cont…...

Amazon CodeWhisperer 免费 AI 代码生成助手体验分享
今年上半年,亚马逊云科技正式推出了实时AI编程助手 Amazon CodeWhisperer,还提供了供所有开发人员免费使用的个人版版本。经过一段时间的体验,我觉得 CodeWhisperer 可以处理编程工作中遇到的很多问题,并且帮助开发人员提高编程效…...

Spring Cloud Gateway 网关路由
一、路由断言 路由断言就是判断路由转发的规则 二、路由过滤器 1. 路由过滤器可以实现对网关请求的处理,可以使用 Gateway 提供的,也可以自定义过滤器 2. 路由过滤器 GatewayFilter(默认不生效,只有配置到路由后才会生效&#x…...

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解
1,spring-data-redis官网 1)特点 提供了对不同Redis客户端的整合(Lettuce和Jedis)提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…...

C语言:内存函数
创作不易,友友们给个三连吧!! C语言标准库中有这样一些内存函数,让我们一起学习吧!! 一、memcpy函数的使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 使…...

Go+:一种简单而强大的编程语言
Go是一种简单而强大的编程语言,它是在Go语言之上构建的,旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义,因此Go开发人员可以很快上手Go,同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…...

【开源】SpringBoot框架开发数字化社区网格管理系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5.1 查询企事业单位5.2 查询流动人口5.3 查询精准扶贫5.4 查询案件5.5 查询人口 六、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数字化社区网格管理系统…...

Lua可变参数函数
基础规则 lua传入参数给一个function时采用的是“多余部分被忽略,缺少部分有nil补足”的形式: function f(a, b)return a or b endCALL PARAMETERS f(3) a3, bnil f(3, 4) a3, b4 f(3, 4, 5) a3, b4 (5 is discarded) unpack/pack…...

Nginx实战:3-日志按天分割
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、方式1:定时任务执行分割脚本 1.分割日志脚本 2.添加定时任务 二、方式2:logrotate配置分割 1.logrotate简单介绍 2.新增切割ngi…...

springmvc中的数据提交方式
一、单个数据提交数据 jsp代码: <h2>1单个数据提交</h2> <form action"${pageContext.request.contextPath}/one.action">name<input name"myname"/><br>age<input name"age"><input type&…...

unity2017 遇到visual studio 2017(社区版) 30日试用期到了
安装unity2017 遇到visual studio 2017 30日试用期到了,网上百度搜了好多方法都没有成功。 最后用了这个方法: 1)启动vs2017,在弹出要登录的窗口之前,迅速的点击工具-》选项-》账户,勾选在添加账户或对账户重新进行身…...

Netty应用(六) 之 异步 Channel
目录 12.Netty异步的相关概念 12.1 异步编程的概念 12.2 方式1:主线程阻塞,等待异步线程完成调用,然后主线程发起请求IO 12.3 方式2:主线程注册异步线程,异步线程去回调发起请求IO 12.4 细节注释 12.5 异步的好处…...

STM32CubeMx+MATLAB Simulink串口输出实验,UART/USART串口测试实验
STM32CubeMxMATLAB Simulink串口输出实验...

【51单片机】串口通信实验(包括波特率如何计算)
目录 串口通信实验通信的基本概念串行通信与并行通信异步通信与同步通信单工、 半双工与全双工通信通信速率 51单片机串口介绍串口介绍串口通信简介串口相关寄存器串口工作方式方式0方式1方式 2 和方式 3 串口的使用方法(计算波特率) 硬件设计软件设计1、…...

Kafka零拷贝技术与传统数据复制次数比较
读Kafka技术书遇到困惑: "对比传统的数据复制和“零拷贝技术”这两种方案。假设有10个消费者,传统复制方式的数据复制次数是41040次,而“零拷贝技术”只需110 11次(一次表示从磁盘复制到页面缓存,另外10次表示10个消费者各自…...

npm ERR! network This is a problem related to network connectivity.
遇到 ETIMEDOUT 错误时,这表明npm尝试连接到npm仓库时超时了,这通常是由网络连接问题引起的。这可能是因为网络不稳定、连接速度慢、或者你的网络配置阻止了对npm仓库的访问。以下是一些解决这个问题的步骤: 1. 检查网络连接 首先ÿ…...

【SQL高频基础题】619.只出现一次的最大数字
题目: MyNumbers 表: ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项(换句话说,在SQL中,该表没有主键)。 这张表的每…...

STM32F1 - GPIO外设
GPIO 1> 硬件框图2> 工作模式 1> 硬件框图 2> 工作模式 C语言描述 /** * brief Configuration Mode enumeration */typedef enum { GPIO_Mode_AIN 0x0, // Analog Input 模拟输入 GPIO_Mode_IN_FLOATING 0x04, // input floating 浮空输入GPIO_Mode_I…...

新增同步管理、操作日志模块,支持公共链接分享,DataEase开源数据可视化分析平台v2.3.0发布
2024年2月5日,DataEase开源数据可视化分析平台正式发布v2.3.0版本。 这一版本的功能升级包括:新增“同步管理”功能模块,用户可通过此模块,将传统数据库中的数据定时同步到Apache Doris中,让数据分析更快速࿱…...

跟着pink老师前端入门教程-day19
一、移动WEB开发之流式布局 1、 移动端基础 1.1 浏览器现状 PC端常见浏览器:360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器、搜狗浏览器、IE浏览器。 移动端常见浏览器:UC浏览器,QQ浏览器,欧朋浏览器࿰…...

ChatGPT学习第一周
📖 学习目标 掌握ChatGPT基础知识 理解ChatGPT的基本功能和工作原理。认识到ChatGPT在日常生活和业务中的潜在应用。 了解AI和机器学习的基本概念 获取人工智能(AI)和机器学习(ML)的初步了解。理解这些技术是如何支撑…...

爬爬爬——今天是浏览器窗口切换和给所选人打钩(自动化)
学习爬虫路还很长,第一阶段花了好多天了,还在底层,虽然不是我专业要学习的语言,和必备的知识,但是我感觉还挺有意思的。加油,这两天把建模和ai也不学了,唉过年了懒了! 加油坚持就是…...

Netty应用(五) 之 Netty引入 EventLoop
目录 第三章 Netty 1.什么是Netty? 2.为什么需要使用Netty? 3.Netty的发展历程 4.谁在使用Netty? 5.为什么上述这些分布式产品都使用Netty? 6.第一个Netty应用 7.如何理解Netty是NIO的封装 8.logback日志使用的加强 9.Ev…...
【c++基础】国王的魔镜
说明 国王有一个魔镜,可以把任何接触镜面的东西变成原来的两倍——只是,因为是镜子嘛,增加的那部分是反的。 比如一条项链,我们用AB来表示,不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话,魔镜会把…...

配置DNS正反向解析服务!!!!
一.准备工作 #关闭防火墙和selinux,或者允许服务通过 [rootnode ~]# nmcli c mod ens32 ipv4.method manual ipv4.address 192.168.32.133/24 ipv4.gateway 192.168.32.2 ipv4.dns 192.168.32.132 [rootnode ~]# nmcli c reload [rootnode ~]# nmcli c up ens32[rootnode ~]# …...

大模型2024规模化场景涌现,加速云计算走出第二增长曲线
导读:2024,大模型第一批规模化应用场景已出现。 如果说“百模大战”是2023年国内AI产业的关键词,那么2024年我们将正式迈进“应用为王”的新阶段。 不少业内观点认为,2024年“百模大战”将逐渐收敛甚至洗牌,而大模型在…...

Gitlab和Jenkins集成 实现CI (三)
Gitlab和Jenkins集成 实现CI (一) Gitlab和Jenkins集成 实现CI (二) Gitlab和Jenkins集成 实现CI (三) 自动部署 配置免密ssh 进入http服务器 生成ssh密钥 ssh-keygen -t rsa进入jenkins(容器) 拷贝公钥 ssh-copy-id http服务器用户名http服务器ip #输入http服务器密码配…...