【实战】Kafka Producer实战——小程序调查问卷

it2023-06-20  74

文章目录

小程序编译运行-效果预览准备工作技术流程图接口文档 业务开发pom依赖公共类工具类配置类conf资源类resouce配置文件yml写业务检验 Kafka Producer集成单例Https解决本地443端口号冲突解决待解决将windows文件压缩tgzlinux文件上传linux修改项目配置解决centos7端口443占用验证https线上运行成功启动脚本解决:Linux下-bash: nohup: command not found或者bash: nohup: 未找到命令的问题解决安全组443 小程序上传开发工具微信公众平台配置小程序文件小程序编译运行-效果预览centos的kafka环境配置解决物理内存不足 JVM调优

小程序编译运行-效果预览

准备工作

技术

流程图

接口文档

问题 选项、返回结果、结果汇总报告

业务开发

pom依赖

<!-- fastjson 尽量保持更新,预防bug--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.74</version> </dependency> <!-- guava支持--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency> <!-- 代码生成lombok,需要配合idea插件--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> <scope>provided</scope> </dependency>

公共类

封装统一返回,泛型 跨域问题

com.bennyrhys.kafka_study1.wechat.common.BaseResponseVO

package com.bennyrhys.kafka_study1.wechat.common; import java.util.UUID; import lombok.Data; /** * @author : bennyrhys * @description : 公共返回对象 **/ @Data public class BaseResponseVO<M> { private String requestId; private M result; public static<M> BaseResponseVO success(){ BaseResponseVO baseResponseVO = new BaseResponseVO(); baseResponseVO.setRequestId(genRequestId()); return baseResponseVO; } public static<M> BaseResponseVO success(M result){ BaseResponseVO baseResponseVO = new BaseResponseVO(); baseResponseVO.setRequestId(genRequestId()); baseResponseVO.setResult(result); return baseResponseVO; } private static String genRequestId(){ return UUID.randomUUID().toString(); } }

com.bennyrhys.kafka_study1.wechat.common.CorsFilter

package com.bennyrhys.kafka_study1.wechat.common; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Configuration; /** * @author : bennyryhs * @description : 跨域问题解决 **/ @WebFilter(filterName = "CorsFilter") @Configuration public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); } }

工具类

json文件读取(object、array)类型

com.bennyrhys.kafka_study1.wechat.utils.FileUtils

package com.bennyrhys.kafka_study1.wechat.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.Optional; import lombok.Cleanup; import lombok.extern.slf4j.Slf4j; /** * @author : bennyrhys * @description : 文件工具类 **/ @Slf4j public class FileUtils { public static String readFile(String filePath) throws IOException { @Cleanup BufferedReader reader = new BufferedReader( new FileReader(new File(filePath)) ); String lineStr = ""; StringBuffer stringBuffer = new StringBuffer(); while ((lineStr = reader.readLine()) != null) { stringBuffer.append(lineStr); } return stringBuffer.toString(); } public static Optional<JSONObject> readFile2JsonObject(String filePath){ try { String fileContent = readFile(filePath); log.info("readFile2Json fileContent: [{}]" , fileContent); return Optional.ofNullable(JSON.parseObject(fileContent)); } catch (IOException e) { e.printStackTrace(); } return Optional.empty(); } public static Optional<JSONArray> readFile2JsonArray(String filePath){ try { String fileContent = readFile(filePath); log.info("readFile2JsonArray fileContent: [{}]" , fileContent); return Optional.ofNullable(JSON.parseArray(fileContent)); } catch (IOException e) { e.printStackTrace(); } return Optional.empty(); } }

配置类conf

实体类 com.bennyrhys.kafka_study1.wechat.conf.WeChatTemplateProperties

package com.bennyrhys.kafka_study1.wechat.conf; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import java.util.List; @Data @Configuration @ConfigurationProperties(prefix = "template") /** * 存储模板调查结果 */ public class WeChatTemplateProperties { private List<WechatTemplate> templates; private int templateResultType; // 结果类型 0-文件 1-数据库 2-es private String templateResultFilePath; // 结果文件路径 /** * 存储模板 */ @Data public static class WechatTemplate { private String templateId; private String templateFilePath; private boolean active; } }

资源类resouce

template

[{ "questionId": "1", "question": "今天几号", "answer": "", "options": [ {"label": "1号", "value": "A"}, {"label": "2号", "value": "B"}, {"label": "3号", "value": "C"}, {"label": "4号", "value": "D"} ]}, { "questionId": "2", "question": "你喜爱的颜色", "answer": "", "options": [ {"label": "红色", "value": "A"}, {"label": "黄色", "value": "B"}, {"label": "绿色", "value": "C"}, {"label": "紫色", "value": "D"} ]} ]

kafka_study1/src/main/resources/templates/templateResult.json

{ "templateId": "001", "totalNumber": "102", "statistics": [ { "questionId": "1", "question": "今天几号", "answers": [ {"label": "A", "value": 10}, {"label": "B", "value": 50}, {"label": "C", "value": 12}, {"label": "D", "value": 17} ] }, { "questionId": "2", "question": "你喜爱的颜色", "answers": [ {"label": "A", "value": 12}, {"label": "B", "value": 52}, {"label": "C", "value": 17}, {"label": "D", "value": 17} ] } ] }

配置文件yml

application.yml

server: port: 8080 template: templates: - {"templateId":"1", "templateFilePath":"E:/JAVA/kafka_study1/src/main/resources/templates/template.json", "active":true} - {"templateId":"2", "templateFilePath":"E:/JAVA/kafka_study1/src/main/resources/templates/template.json", "active":false} template-result-type: 0 # 结果类型 0-文件 1-数据库 2-es(注意驼峰命名改横线小写链接) template-result-file-path: "E:/JAVA/kafka_study1/src/main/resources/templates/templateResult.json"

写业务

https://github.com/bennyrhys/kafka_study.git

检验

查询模板信息 http://localhost:8080/v1/template

查询模板统计结果 http://localhost:8080/v1/template/result 提交调查问卷结果 windows通过gitbash模拟linux环境 post 返回结果 requestId":“0725ef59-52fb-432c-aef5-4276cc25ae37”,“result”:null}

-- 查询模板信息 curl -XGET http://localhost:8080/v1/template -- 查询模板统计结果 curl -XGET http://localhost:8080/v1/template/result -- 传入调查问卷结果 curl -XPOST -H "Content-Type:application/json; charset=UTF-8" http://localhost:8080/v1/template/report -d \ '{ templateId:"001", result:[ {"questionId":"1","question":"今天几号","answer":"A"}, {"questionId":"2","question":"你喜爱的颜色","answer":"B"} ] }' netstat -ano | findstr 443

Kafka Producer集成单例

kafka的Producer是线程安全的,实际生成环境不建议Producer创建多回。 如果多线程情况下创建多个producer,性能消耗比想象中消耗要大。甚至不如单线程。 因为producer的send是 往中间队列中存入数据, 后台线程将数据批量的刷给服务器。创建多个producer使频繁的上下文争抢,上下文切换

而每次进入controller->service就相当于创建一个新实例,为了防止producer被创建多次,应该单独把producer封装到common或utils或conf

Https

SSL的AC证书认证 域名备案20个工作日左右 同一个证书只能绑定一个域名 绑定域名不包含二三级子域名

证书下载 因为springBoot内置的tomcat

检验证书+添加二级域名:域名解析会多出一行txt,

下载出 的证书及密码

启动协议变为https

server: port: 443 ssl: key-store: 3974629_www.996cloud.work.pfx # 证书的文件名 key-store-password: O4d8Fl8t

准备上传服务器的文件

解决本地443端口号冲突

windows查看端口号 C:\Users\rxguo>netstat -ano |findstr "443"

赫然发现443被一个pid为7296的进程占用着. 查看该pid对应的程序: tasklist |findstr "进程id号" 于是我尝试杀掉该进程:被拒绝 taskkill /f /t /im "进程id或者进程名称"

打开VM虚拟机,点击菜单中的“编辑-首选项”,把共享虚拟机给关闭;

解决

https://localhost/v1/template

待解决

查logbak.xml

将windows文件压缩tgz

tar -zcvf 文件.tgz 文件名

linux文件上传

yum install -y lrzsz

linux修改项目配置

地址和ip地址

root@iZ2ze21075lo3b5h7k3wozZ wechat]# ll total 29468 -rw-r--r-- 1 root root 30175119 Oct 21 17:29 wechat-template.tgz [root@iZ2ze21075lo3b5h7k3wozZ wechat]# tar -zxf wechat-template.tgz [root@iZ2ze21075lo3b5h7k3wozZ wechat]# ll total 29472 drwxr-xr-x 3 1173931 1049089 4096 Oct 21 17:27 wechat-template -rw-r--r-- 1 root root 30175119 Oct 21 17:29 wechat-template.tgz [root@iZ2ze21075lo3b5h7k3wozZ wechat]# cd wechat-template [root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# ll total 32076 -rw-r--r-- 1 1173931 1049089 4554 Oct 21 16:57 3974629_www.996cloud.work.pfx -rw-r--r-- 1 1173931 1049089 819 Oct 21 17:07 application.yml -rw-r--r-- 1 1173931 1049089 32825383 Oct 21 17:25 kafka-template.jar drwxr-xr-x 2 1173931 1049089 4096 Oct 21 17:21 templates [root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# vi application.yml

解决centos7端口443占用

停掉之前的项目

cd /usr/local/java/tomcat/apache-tomcat-8.5.40/bin/ netstat -nap | grep 443

验证https线上运行成功

https://www.996cloud.work/v1/template 注意因为线上环境缺少kafka所以会报warn

启动脚本

[root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# vi start.sh # !/bin/bash nohub java -jar wechat-template.jar & // 赋予脚本执行权限 -rw-r--r-- 1 root root 51 Oct 22 10:36 start.sh [root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# chmod u+x start.sh // 有了权限文件名变为绿色 [root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# ll total 32080 -rw-r--r-- 1 1173931 1049089 4554 Oct 21 16:57 3974629_www.996cloud.work.pfx -rw-r--r-- 1 1173931 1049089 786 Oct 22 10:21 application.yml -rwxr--r-- 1 root root 51 Oct 22 10:36 start.sh

解决:Linux下-bash: nohup: command not found或者bash: nohup: 未找到命令的问题

不要错写成nohub是nohup https://blog.csdn.net/qq_40241957/article/details/98584207

解决安全组443

1 安全组的端口添加绿卡443 2 centos的防火墙关闭

[root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# systemctl status fillwalld Unit fillwalld.service could not be found. [root@iZ2ze21075lo3b5h7k3wozZ wechat-template]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1)

小程序上传

开发工具

小程序 https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html nodejs https://nodejs.org/en/

配置node环境变量 检验node

C:\Users\rxguo>node -v v12.19.0

微信公众平台

appid:wx9018260c5501cfb1238

配置小程序文件

解压qe文件

删除自动生成的dist文件

关注package.json,其中config.ts在src目录下 修改config.ts,修改后端对应地址 export const baseUrl: string = 'https://www.996cloud.work'

git bash右键,命令行编译 注意:install只会会产生node_moudle 模板文件特别大

// 检验是否有cnpm cnpm -v // 没有则安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm install -g @tarojs/cli@2.0.6 cnpm install npm run build:weapp

注意如果taro 出现问题 taro info 查看版本信息

生成dist文件,就是要发布到微信程序里的内容

小程序编译运行-效果预览

centos的kafka环境配置

见博主的【消息队列】kafka 文章

解决物理内存不足 JVM调优

Java HotSpot™ 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000794500000, 576716800, 0)

停止当前后台运行的jar

// 找到java对应的pid netstat -anp // 杀死进程pid kill -9 进程pid

重新修改启动脚本

nohup java -Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m -jar wechat-template.jar &

JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m" java -Xms512m -Xmx512m -XX:+UseG1GC -XX:+PrintGCDetails -jar 项目.jar

命令行查看内存占用的pid top 选着性 kill -9 pid号

mysql的进程没法直接关闭一直变动 https://blog.csdn.net/chinabluexfw/article/details/7170123?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight

瑞 新 认证博客专家 分布式 Java 架构 求职中 • Java全栈养成计划公众号 • 让我遇见相似的灵魂回复领取:竞赛 书籍 项目 面试左手代码,右手吉他,这就是天下:如果有一天我遇见相似的灵魂 那它肯定是步履艰难 不被理解 喜黑怕光的。如果可以的话 让我触摸一下吧 它也一样孤独得太久。 不一样的文艺青年,不一样的程序猿。
最新回复(0)