一文快速掌握链路追踪、异步任务、手机号邮箱号登录、大模型调用
zipkin的使用
下载zipkin(https://labilibili.com/package/zipkin.jar)
进入zipkin的jar包解压后的路径,本机启动zipkin
服务中使用slueth传递请求信息
zipkin是将请求链路以可视化的形式展示出来,而slueth则是将请求相关信息发送给zipkin
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> 依赖版本号在项目父pom.xml文件中查看,后续同理
编写配置
spring: zipkin: base-url: http://localhost:9411 zipkin服务地址 sender: type: web 使用http请求发送,值为rabbit和Kafka则是用消息队列发送请求数据 sleuth: sampler: probability: 1 sleuth 日志记录采样率,1为100%,默认为0.1即10%
发送请求后在浏览器地址栏中输入localhost:9411查看控制台
单服务调用
跨服务调用
completableFuture的使用
completableFuture是一种便捷、功能相当强大的异步任务框架,接下来举例最常用的几种功能
单个执行异步任务
CompletableFuture.runAsync(()->{ log.info(""); log.info(""); }); 若需要执行的只有一句可以简化为Lambda形式 CompletableFuture.runAsync(()-> log.info(""));
异步任务的回调
CompletableFuture.runAsync(() -> minioService.uploadImgFile(coverFileName, coverMultipartFile.getInputStream(), imgContentType)).handle((result, ex) -> { if (ex != null) { 异步任务出现异常后可以进行相应处理 log.error("uploadimgfail"); } return null; });
顺序执行异步任务
这种情况下就需要声明执行异步任务的对象来传递后续顺序执行异步任务时的参数,只单个执行异步任务可以不用声明该对象 CompletableFuture<Void> uploadVideoFuture = CompletableFuture.runAsync(() -> { log.info("111"); log.info("222"); }); 在上一个异步任务对象的任务执行完后才启动 CompletableFuture thenRunFuture = uploadVideoFuture.thenRun(() -> client.sendUploadNotice(new UploadVideo().setVideoId(video.getId()).setVideoName(video.getName()).setUrl(url).setHasCover(false)));
同时等待多个异步任务执行完成再开启新异步任务、获取异步任务返回值、阻塞主线程
创建第一个异步任务 CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } return "结果1"; }); 创建第二个异步任务 CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } return "结果2"; }); 创建第三个异步任务 CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } return "结果3"; }); 合并所有异步任务,并等待它们全部完成 CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3); 等待所有任务完成,并处理结果 allOf.thenRun(() -> { try { 获取每个任务的结果 String result1 = future1.get(); String result2 = future2.get(); String result3 = future3.get(); 输出结果 log.info("所有任务完成"); log.info("结果1: " + result1); log.info("结果2: " + result2); log.info("结果3: " + result3); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }).join(); 阻塞主线程直到所有任务完成(tips:该特性在gateway中有新起效,gateway默认是异步非阻塞的,若在该服务中远程调用其他服务接口会报错,但使用CompletableFuture又可能有需求需要阻塞主线程的情况,此时可以用该功能) log.info("主线程结束"); }
手机号登录
引入依赖
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-dysmsapi</artifactId> </dependency>
核心工具类
可自助调整超时时间 System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000"); 用阿里云中短信模版中的参数初始化acsClient IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); IAcsClient acsClient = new DefaultAcsClient(profile); 组装请求对象 SendSmsRequest request = new SendSmsRequest(); 必填:待发送手机号 request.setPhoneNumbers(phone); 必填:短信签名-可在短信控制台中找到 request.setSignName("labilibili"); 必填:短信模板-可在短信控制台中找到 request.setTemplateCode("SMS_295400185"); 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为 request.setTemplateParam("{\"code\":\"" + code + "\"}"); 选填-上行短信扩展码(无特殊需求请忽略此字段) request.setSmsUpExtendCode("90997"); 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者 request.setOutId("yourOutId"); 此处可能会抛出异常,注意catch SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); return sendSmsResponse; }
发送邮箱验证码
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
配置参数
spring: mail: host: smtp.qq.com default-encoding: UTF-8 username: ********** password: dawasd 这个密码需要去qq邮箱中获取授权码 properties: mail: smtp: auth: true starttls: enable: true required: true socketFactory: port: 465 这个配置是因为在线上环境下原默认端口会被阿里云判定为不安全,因此需要 class: javax.net.ssl.SSLSocketFactory 换端口 fallback: false
发送验证码
@Resource 注入发送邮箱的bean public JavaMailSender mailSender; SimpleMailMessage message = new SimpleMailMessage(); Random random=new Random(); 填写要接收验证码的邮箱 message.setTo(mailNumber); 邮箱主题 message.setSubject("验证码"); String captcha=""+random.nextInt(10)+random.nextInt(10)+random.nextInt(10)+random.nextInt(10)+random.nextInt(10)+random.nextInt(10); redisTemplate.opsForValue().set(mailNumber,captcha); 存储验证码到内容中 message.setText("labilibilibili验证码:"+captcha); 填装发送者 message.setFrom(from); log.info("send"); log.info(from); mailSender.send(message);
最后,宣传一下自己的仿b站前后端分离微服务项目,依赖版本号也在该项目的父pom.xml中
实现了以下功能:
视频的上传、查看与上传时获取封面
视频的点赞、评论、可同时新增和删除多个收藏记录的收藏、多功能的弹幕
用户的个人信息查看编辑、用户之间的关注
用户的个人主页权限修改、查看、由个人主页权限动态决定的用户个人主页内容的获取
手机号、邮箱、图形验证码的多种方式登录
支持临时会话的服务器为代理的一对一实时私聊
基于讯飞星火的文生文、文生图、(全网首发)智能PPT
关注up动态视频、评论、点赞、私聊消息的生成与推送
基于es实现的视频和用户的聚合搜索、推荐视频
网关的路由和统一鉴权与授权
基于双token的七天内无感刷新token
防csrf、xss、抓包、恶意上传脚本攻击
统一处理异常和泛型封装响应体、自定义修改响应序列化值
简易的仿redis缓存读取与数据过期剔除实现
xxl-job+ redis+ rocketmq+ es+ 布隆过滤器的自定义es与mysql数据同步
slueth+zipkin的多服务间请求链路追踪
集中多服务日志到一个文件目录下与按需添加特定内容入日志
多服务的详细接口文档
项目地址LABiliBili,github地址GitHub - aigcbilibili/aigcbilibili: 仿bilibili前后端实现,演示地址https://labilibili.com/video/演示.mp4,如果大家觉得有帮助的话可以去github点个小星星♪(・ω・)ノ
#秋招##美团##字节跳动##阿里巴巴##腾讯#该专栏存放前后端分离仿b站微服务项目相关教程