暂时未有相关云产品技术能力~
一、背景vue-element-admin框架之所以能够快速定制应用,得益于其通配的CRUD操作,属性配置多样化且个性化,能够满足绝大部分开发需求,也方便了代码生成。可以深入学习重点源文件是:src/components/Crud/crud.js,一共863行代码,以及下图中其它四个vue组件,形成了对通用CRUD操作的高级封装。来一段该文件的历史:在该文件之前有一个老版本的文件,在src/mixins文件夹下。有4处使用的地方,在源码版本记录中观察到:在2019年12月9日老版本的文件停止更新了,重新添加了src/components/crud/crud.js以及其它组件,包括表单、分页、搜索框、表格;在2019年12月12日更改了现在的名字,并以此为基础进行迭代。二、文件一览共计9个函数,最重要的就是CRUD(options)函数,封装了配置项、方法、钩子函数。CRUD(options)callVmHook(crud, hook) 调用钩子函数mergeOptions(src, opts) 合并配置项,将传入的参数合并到当前实例中presenter(crud) 生成crudheader() 头部pagination() 分页form(defaultForm) 表单crud(options = {})三、配置项默认配置项有:四、方法4.1 普通方法4.2 钩子函数钩子函数应该说是做的很精细,包含各个用户操作的事件。钩子函数与vue生命周期的执行顺序应该是我们最关注的,因为事件的起始影响着编程的思路。五、小试牛刀编写后台接口引入各个组件和数据API接口函数声明默认表格对象defaultForm该对象对应着表格要显示的数据列定义函数cruds()该函数返回第二节中的CRUD(options)实例,参数options是一个可配置对象,根据需求更改配置元素的值。混入对象通过vue混入属性,将通用CRUD暴露的组件函数拿过来mixins: [presenter(), header(), form(defaultForm), crud()]请求后台数据通过钩子函数CRUD.HOOK.beforeRefresh六、拨云见雾通用组件怎么运行起来的?离不开assign,vm.$option,callVm
一、背景当我们为甲方服务提供软件开发服务时,需要按照甲方的要求去修改软件的标识,对于Maven项目来说就对应着groupId,一般地写对方公司的域名,如com.example。因此,项目中使用到的原来的代码需要赋予其新的标识。二、具备的能力2.1 IDEAIDEA的版本为2020.2。1.IDEA的全文检索,快捷键 Ctrl + Shift + R利用该功能可以查找和修改作用域为整个项目的相关字符串。2.文件夹迁移功能,move命令项目的包对应着操作系统的文件,如com.example对应着com\example,因此修改包名其实就是把文件迁移到另一个文件夹下。2.2 Maven多模块项目一般地,Maven多模块项目的包名package和groupId保持一致,这样对文件的配置十分有利。三、步骤3.1 移动包如图所示,在某一个子模块的java根目录下,选中包名右键选择重构Refactor。接着选择 Move Package or Directory。3.2 选择重构的条件即选择第一个点击确认完成迁移IDEA会检索所有项目中和该包有关的文件夹进行迁移3.3 清扫战场迁移完毕后,我们会发现,项目根目录及test测试目录下会留下原来的包,迁移完毕后,遗留包成为空的文件夹,删除即可。3.4 小心毒刺系统的配置会影响到程序的运行,比如原来的组件扫描的包名、序列化的问题会导致程序运行不成功。因此,这些“毒刺”需要剔除。3.4.1 redis序列化问题3.4.1.1 说明笔者对redis的键值都进行了序列化的设置,因此,重启后台后,访问到的redis序列化对象失败导致前台访问接口失败。3.4.1.2 解决清空redis 库即可。3.4.2 组件扫描3.4.2.1 说明ComponentScan、EnableJpaRepositories、EntityScan注解都和扫描的包有关,默认扫描的包为启动类所在的包,因此如果maven模块包命名改变会影响注解的包值3.4.2.2 解决修改即可扫描包名四、其它对于其它标识需要修改的,通过IDEA的全局搜索工具可以替代你想要的任何字符。
一、问题描述在查询的时候,发现点击后台的分页器数字,第2页时候,数据还是和第1页的一致。就看后台的数据库打印语句,如下所示。点击第一页和第二页都是这个,limit后的参数只有一个,前期做过类似,点击第二页分页的时候,语句是LIMIT ?,?ON ap.id = a.project_id ORDER BY a.create_time DESC LIMIT ?二、分析步骤1.首先开始怀疑的是自己的分页对象出现了问题,因为MySQL ORM框架使用了JPA框架遗留的代码。将spring-data的分页对象org.springframework.data.domain.Pageable转成了mybatis-plus的分页对象com.baomidou.mybatisplus.extension.plugins.pagination.Page<T>。debug后,Page<T>的 current 和 size 都是存在且对应前台传来的值。2.接着怀疑是mybatis-plus的拦截器顺序问题,因为项目里写了数据权限的拦截器,在研究数据权限拦截器的时候就看到有说拦截器添加顺序会影响到SQL语句拼接的正确性。对比了正常的添加顺序后,这部分也没有问题。 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //添加数据权限处理器,注意顺序,先数据权限再分页 MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor(); // 添加自定义的数据权限处理器 dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler()); interceptor.addInnerInterceptor(dataPermissionInterceptor); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; }3.发现这两部分都没问题后,决定还是debug一下分页拦截器。重要的分页SQL语句拼接函数如下。DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());进入到里面,这里数据库使用的MySQL。public class MySqlDialect implements IDialect { @Override public DialectModel buildPaginationSql(String originalSql, long offset, long limit) { StringBuilder sql = new StringBuilder(originalSql).append(" LIMIT ").append(FIRST_MARK); if (offset != 0L) { sql.append(StringPool.COMMA).append(SECOND_MARK); return new DialectModel(sql.toString(), offset, limit).setConsumerChain(); } else { return new DialectModel(sql.toString(), limit).setConsumer(true); } } }可以看到偏移量offset至关重要,决定了拼接的条件判断。又发现,offet的值和current相关,根据排查结果来看,current 是正常传值的。default long offset() { long current = this.getCurrent(); return current <= 1L ? 0L : Math.max((current - 1L) * this.getSize(), 0L); }因此到这里我们就会发现,是offset的真实值不正确。当后台前端页面传来的current 是0时,offset等于0。当后台前端页面传来的current 是1时,offset依旧等于0。而回到拼接函数buildPaginationSql中,不等于0的时候才会有 两个参数的拼接。至此,这个问题解决了,就是在对象转换时,没有对current的值进行 + 1三、解决方案public class MyPage<T> extends Page<T> { /** * @Description: 将spring的分页对象转成Mybatis * @param pageable: * @return: null **/ public MyPage(Pageable pageable) { this.setSize(pageable.getPageSize()); this.setCurrent(pageable.getPageNumber() + 1); } }四、总结多用编译器的debug细节问题还是要注意,哪怕一个变量
一、背景介绍前面做过一个类似的项目,使用layui组件进行前端页面的开发,整个项目前后端没有解耦。这次想换个开发方式,将前后端进行分离开发。期间学习了Vue,扩充了技术栈,形成了后端Java SpringBoot + 前端Vue的一个技术能力。有了技术能力后,就需要进行历练,毕竟学而不思则罔,方法就是通过开发一个后台管理系统来丰富自己做项目的经验,提升技术能力。开发的后台管理系统是基于某个行业进行数字化、信息化。管理系统分为通用模块和特色模块,通用模块指的是系统的一些管理功能,如菜单管理、用户管理、角色管理等,这些通用的模块属于重复造轮子的工作。特色模块就是系统本身要满足的业务需求,即在某个行业的某个方向上的功能。当然,既然有重复的内容,工作就不会从零开始,而是将大多数时间用在业务模块的开发上。因此可以依托一个开源的后台管理模块作为基础,进行二次开发。因此在GitHub上搜索关键词 spring vue ,通过检索星最多的项目,就找到了该项目。二、项目介绍后端GitHub访问地址,后端Gitee访问地址。前端GitHub访问地址,前端Gitee访问地址。项目的版权是 Apache Licence 2.0,也就是说该开源项目能够进行二次开发和商业使用。项目总体来说很易于把控和操作。项目技术栈:Spring Boot 2.1.0 、 Spring Data JPA、 JWT、Spring Security、Redis、Vue。其中Spring Boot 2.1.0、 JWT、Redis、Vue是熟悉的中间件,Spring Boot Jpa、Spring Security是不数字的部分,但是万变不离其宗,都是为了解决同一问题的不同方式。之所以使用Spring Boot Jpa还有一个有趣的原因,因为太多项目是采用的是Mybatis,作者就想使用用JPA ORM存储框架。有些大佬就是有个性。咱们必须跟着大佬的步伐,个性一把,以前用MyBatis,现在也要学他丫的,学SpringData JPA。笔者花了半天的时间,熟悉整体功能。软件版本是2.6。功能有:系统功能说明用户管理提供用户的相关配置,新增用户后,默认密码为123456角色管理对权限与菜单进行分配,可根据部门设置角色的数据权限菜单管理已实现菜单动态路由,后端可配置化,支持多级菜单部门管理可配置系统组织架构,树形表格展示岗位管理配置各个部门的职位系统日志记录用户操作日志与异常日志,方便开发人员定位排错字典管理可维护常用一些固定的数据,如:状态,性别等SQL监控采用druid 监控数据库访问性能,默认用户名admin,密码123456定时任务整合Quartz做定时任务,加入任务日志,任务运行情况一目了然代码生成高灵活度生成前后端代码,减少大量重复的工作任务邮件工具配合富文本,发送html格式的邮件七牛云存储可同步七牛云存储的数据到系统,无需登录七牛云直接操作云数据支付宝支付监控服务器的负载情况服务监控整合了支付宝支付并且提供了测试账号,可自行测试运维管理一键部署你的应用可以看到,系统基本的功能是有了,其中代码生成能够直接生成前后端代码,能帮开发者节省大量的CRUD和写前端界面交互的时间。三、项目结构熟悉任何一个项目都要有庖丁解牛之本领,才能领会项目构造。从0到1去掌握一个项目,必然要是采用演进的方式,随着知识面的不断补充,对项目越来越深入理解。对项目有一定的知识基础,掌握项目会变得快速,如果没有基础,慢慢研究各个组件,也会达到对项目的掌握,无非就是花费时间较长而已。接着看一下项目的目录结构,我们都知晓,项目结构的好坏决定一个项目的解耦的程度和灵活度。后端采用的是Maven多模块的开发方式,根据功能将项目进行划分,很容易地将开发工作进行分配,后期添加模块也非常容易。3.1 后端目录结构后端目录结构:- eladmin-common 公共模块 - annotation 为系统自定义注解 - aspect 自定义注解的切面 - base 提供了Entity、DTO基类和mapstruct的通用mapper - config 自定义权限实现、redis配置、swagger配置、Rsa配置等 - exception 项目统一异常的处理 - utils 系统通用工具类 - eladmin-system 系统核心模块(系统启动入口) - config 配置跨域与静态资源,与数据权限 - thread 线程池相关 - modules 系统相关模块(登录授权、系统监控、定时任务、运维管理等) - eladmin-logging 系统日志模块 - eladmin-tools 系统第三方工具模块 - eladmin-generator 系统代码生成模块来看一下Maven依赖关系,从图中也能看出common是公共模块,system是主要模块。该图的打开方式是:system文件夹 -> 右键点击Maven -> Show Diagram -> Project Modules。快捷键是 Ctrl + Alt + U。布局根据自己喜好来定,笔者选择的是继承组布局。3.2 前端目录结构前端目录也是采用的标准的Vue脚手架进行生成的目录,如下所示。 |-- build 构建脚本目录 |--build.js ---- 生产环境构建脚本 |--build-server.js ---- 运行本地构建服务器,可以访问构建后的页面 |--dev-client.js ---- 开发服务器热重载脚本,主要用来实现开发阶段的页面自动刷新 |--dev-server.js ---- 运行本地开发服务器 |--check-version.js ---- 检查npm、node.js版本 |--utils.js ---- 构建相关工具方法 |--vue-loader.conf.js ---- 配置css加载器以及编译css之后自动添加前缀 |--webpack.base.conf.js ---- webpack基本配置 |--webpack.dev.conf.js ----- webpack开发环境配置 |--webpack.prod.conf.js ---- webpack生产环境配置 |-- public:项目公共文件 |-- favicon.ico ---- 标签页图片 |-- index.html ---- 项目配置文件 |-- robot.txt ---- 爬虫范围 |-- node_modules:npm加载项目的依赖模块 |-- src (源码目录,名称不可修改) |-- api:接口文件,与后台进行通信 |-- assets:资源文件,比如存放 css,图片等资源 |-- components:组件文件夹,用来存放 vue 的公共组件(注册于全局,在整个项目中通过关键词便可直接输出) |-- router:用来存放 index.js,这个 js 用来配置路由 |-- store: 用来存放系统状态 |-- utils:用来存放工具类 js,将 js 代码封装好放入这个文件夹可以全局调用(比如常见的 api.js,http.js 是对 http 方法和 api 方法的封装) |-- views:用来放主体页面,虽然和组件文件夹都是 vue 文件,但 views 下的 vue 文件是可以用来充当路由 view 的 |-- main.js:是项目的入口文件,作用是初始化 vue 实例,并引入所需要的插件 |-- app.vue:是项目的主组件,所有页面都是在该组件下进行切换的 |-- setting.js:是项目的配置文件,或者说是存放常量的文件 |-- package.json:npm包配置文件,定义项目的npm脚本、依赖包等信息 |-- README.md:项目的说明文档,markdown格式 四、开发一个新的模块笔者在根目录下新建一个名为test的maven模块,通过该软件提供的代码生成功能生成一个测试界面,并在菜单中显示。效果如下图所示。此时项目结构为:具体开发步骤参见eladmin官方文档——代码生成。五、几点思考JPA知识需要补充,框架原理至少搞懂,应用多看项目里的例子;前端Element UI 组件学习,和蚂蚁Ant Design UI组件相似,组件都差不多;软件设计一定讲究解耦、模块化,方便扩展、管理。六、番外篇6.1 JPA6.1.1 JPA是啥Repository是JPA的中心抽象对象。模型类domain class和序号ID是其类型参数。以接口CrudRepository<T, ID>为例,6个简单的函数能够看出JPA的强大,不需要写任何SQL即可完成复杂的数据操作功能。大家有兴趣地去官网看看介绍文档,写的很容易理解。这玩意说简单点就是通过接口中的方法名自动生成底层SQL语句完成对数据库的操作。当然,你必须按照他的命名规范进行写方法名。public interface CrudRepository<T, ID> extends Repository<T, ID> { <S extends T> S save(S entity); Optional<T> findById(ID primaryKey); Iterable<T> findAll(); long count(); void delete(T entity); boolean existsById(ID primaryKey); // … more functionality omitted. }改造数据表ID变化策略为UUID,做到全局唯一。一对一、一对多、多对多,三种关系表的处理。6.1.2 JPA能干啥不需要写SQL语句,直接通过操作Bean对象,完成对数据库的操作。JPA换库很简单,直接换源就可以完成换库,不需要重写SQL。6.1.3 JPA注意点命名对数据库表和字段的命名使用下划线_进行分割,框架会根据实体驼峰属性自动转换到数据库表带下划线_的字段。
一、 序笔者在进行网页开发过程中需要绘制登录页,一般的登录页就是纯色背景加上用户密码输入框,如果想要复杂且页内元素统一的就需要创作了,而Axure对于图形操作支持不友好,因此就用到PS先行绘制,导出图片到Axure再进行登录页的设计。二、 PhotoShop下载下载链接:https://pan.baidu.com/s/1Qzig4wqxMWcq_G778DXy1Q?pwd=5pth提取码:5pth资源内有各个版本的安装包,按照需要自行下载。三、 PhotoShop 2022安装3.1 下载好后解压得到下述安装包3.2 双击可执行文件双击Set-up.exe可执行文件按照提示完成安装。因为安装的文件很大,因此放到非系统盘里进行安装。3.3 启动界面3.4 安装完成四、 PhotoShop 2022常用功能4.1 抠图常使用是命令是W,配合蒙版和钢笔路径使用能快速抠出带细节的图形,如抠头发丝。4.2 添加光晕找到滤镜——渲染——镜头光晕,调整到需要的效果。4.3 曲线和色阶两大调色法宝,能够调出想要的风格。在实操中,一定要把二者的作用图层调整到所要作用的图层,而不是其下的所有图层都受影响。快捷键是 Ctrl +Alt + J,此时曲线图层的左边会有向下的角标。该功能相当有用。4.4 消除水印快捷键是 J,使用它能擦掉不想要的水印。4.5 偷天换日快捷键是 S,可以将像素进行复制,当水印去的太狠了,用它进行补救。五、 PS素材网5.1 Unsplash质量最高的免费高清图片/摄影照片/设计素材的资源网站之一。Unsplash 是一个高质量摄影照片分享社区,世界上最慷慨的摄影师社区Unsplash超过100万张免费高分辨率图像。所有在Unsplash上发布的照片都可以免费使用,您可以将其用于商业和非商业目的。5.2 iStockiStock是一个在线,免版税的国际微利摄影网站。该网站采用供应商与小额支付商业模式运作模式。网站提供数以百万计的照片,插图,剪贴画,视频和音频轨道。图片价格从1美分至1.5美元。它拥有超过14万艺术家,每月创建和提交将近50万张新照片,插图,视频和音频文件。国内叫Veer 。5.3 其它学会使用图片搜索,假设你找到了相关的图片后,但是还不满意,这时你可以通过网站的图片搜索功能进行查找,可以快速地定位到需要的图片。六、 寻图注意事项找到主题图片很简单,但是找到适合的很难。什么称为适合。颜色和所制作的图片整体需要保持一致,减少后期色阶的调整;方向感和光感一致,避免视觉冲突;所选的物体杂物要少,避免去除的麻烦。
Jeecg-Boot项目工程采用前后端分离开发方式,后端基于 SpringBoot,前端基于 Ant Design,是一款非常不错的学习项目。1 后端 部署流程1.修改配置文件更改数据库、redis的配置。2.maven 打包在项目根路径下,使用命令行 maven package对项目进行打包。在system子模块中的target文件夹下生成 jar 包jeecg-boot-module-system-3.2.0.jar。3.复制到云服务器4.生成数据库运行该sql文件即可。5.使用命令运行后端程序java -jar ./jeecg-boot-module-system-3.2.0.jar2 前端 部署流程1.run serve 和 run build的区别二者都会引用环境文件.env的配置参数run serve 会引用环境文件 .env.development中的配置构建项目run build会引用环境文件.env.production中的配置打包项目,生成dist2.修改环境参数文件.env.productionNODE_ENV=production VUE_APP_API_BASE_URL=http://localhost:8082/jeecg-boot #localhost替换成云服务器的ip地址,即修改接口地址 VUE_APP_CAS_BASE_URL=http://localhost:8888/cas #localhost替换成云服务器的ip地址,即修改单点登录地址 VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview3.打包使用下述命令进行打包。npm run build4.nginx部署修改nginx的配置文件,如下所示。 server { listen 3000; #解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 location / { root C:/MiddleSoftware/jeecg-boot/ant-design-vue-jeecg/dist; index index.html index.htm; if (!-e $request_filename) { rewrite ^(.*)$ /index.html?s=$1 last; break; } } }3 结果运行起来看效果。4 问题总结登录页面的验证码显示404,原因是redis没有连接成功导致生成的验证码字符串保存在redis中进行后续验证,成功后redis的db0库具有下述缓存
1 硬件准备4G DTU 一台USB转232转接线一根485温湿度传感器一个12V电源2个LTE-Cat1物联网卡一张2 拓扑图DTU RS485 <-----> 传感器的485线(A接A,B接B)DTU RS232 <-----> USB转RS232转接器DTU 电源(耳机孔电源)<-----> DC 12V 外接电源传感器电源线 <-----> DC 12V 外接电源3 准备知识3.1 什么是DTU3.1.1 概念DTU(Data Transfer Unit):数据传输单元,专门用于将串口数据转换为IP数据或将IP数据转换为串口数据,进而通过无线通信网络进行传送的终端设备。节省开发时间,快速将设备数据上传到服务器。3.1.2 DTU类型有两种分类方式,其一是按照通信方式分类有以下7类;GPRS4GNB-IoTLORAZigBeeWiFi卫星其二是按照接口类型分类。RS232RS485TTL3.2 RS232RS表示Recommend Standard(推荐标准),串口标准之一,较为常用。工业控制的RS-232口一般只使用RXD、TXD、GND三条线。接口形态为DB9。3.3 RS485RS含义同上。RS232接口,可以实现点对点的通信方式,但不能实现联网功能,随后出现的RS485解决了这个问题。RS485通信网络中一般采用的是主从通信方式。RS485/MODBUS是流行的一种布网方式,实施简单方便 ,支持RS485的仪表很多。13.4 Modbus RTU协议3.4.1 概念Modbus RTU是一种紧凑的,采用二进制表示数据的方式。后续的命令/数据带有循环冗余校验的校验和(CRC16)。Modbus协议是一个Master/Slave架构的协议。和TCP有点类似。一个节点是master节点,其他使用Modbus协议参与通信的节点是slave节点。每一个slave设备都有一个唯一的地址。3.4.2 命令举例请求:01 03 00 00 00 02 C4 0B字节功能含义01设备地址设备地址为103功能码当前为03读取请求00 00设备地址寄存器起始地址,从00 00寄存器开始读取00 02读取寄存器长度读取2个长度,对应回复4个字节C4 0B效验和CRC16效验和回复:01 03 04 00 0C 00 02 BB F1字节功能含义01设备地址设备地址为103功能码当前为03读取回复04数据长度当前为03读取回复00 0C设备地址寄存器1数值00 02读取寄存器长度读取2个长度,对应回复4个字节BB F1效验和CRC16效验和4 期待目标将传感器设备的数据通过4G网络上报给云服务器(已完成)通过网络发送命令给传感器5 调试流程5.1 搭建TCP服务器在服务器上安装Socket程序,启动TCP监听。5.2 配置4G DTU 设置TCP服务器连接设置DTU工作方式为数据透传;设置上述服务器的IP和端口数值;设置消息格式,包括心跳包和注册数据;点击保存参数,点击重启设备。(每一次对设备进行配置后,都需重启生效)在服务器上查看是否收到数据。如果收到数据,表明网络通信服务是OK的。5.3 配置温湿度传感器使用USB转485转接器连接温度传感器,DC 12V电源对传感器进行供电。为避免和其它的传感器地址冲突,设置温度传感器的地址值为3,然后对传感器进行写操作,接着读取数据。可以看到数据采集成功。5.4 设置Modbus主动轮询参数此配置的功能是,DTU可以向传感器发送读取指令03 03 00 00 00 02 C5 E9,对应上一步设置的温度传感器的地址。DTU收到回复数据后,会将字节数组数据按照设置的上传类型【json带IMEI】通过4G网络上传至步骤5.1设置的TCP服务器上。整条数据包格式如下所示。{"IMEI":863488052947903,"time":"2022-06-10 16:03:43","wenshidu":[1,15,3,42]}5.5 集成测试将上述器件进行连接,进行集成测试。线有点多,可以使用并线器。6 结果读取温湿度数据,4个字节,前2个表示温度,后2个表示湿度,拿[1,27,3,6]举例。[1,27] = 0x011B = 0d283 ,除10等于 28.3℃[3,6] = 0x0306 = 0d777,除10等于 77.7 RH
1 ThingsBoard数据库总览ThingsBoard软件版本为 3.3.2。ThingsBoard使用的数据库类型为关系型数据库PostgreSQL。1.1 数据库信息1.1.1 数据库名称数据库名称为thingsboard,数据库名一般和应用名称保持一致。1.1.2 数据库用户名及密码默认的用户名和密码均为postgres。1.1.3 数据库表数据库包含共计40张数据表。1.2 数据库表命名规范首先确定单个单词能否涵盖业务的全部功能;其次按照“业务名称_表的作用”进行细分;最后按照“业务名称_表的作用_状态信息”继续细分;1.3 40张数据表信息按照功能单元分类如下表所示。序号业务名称功能表名描述1规则引擎规则链rule_chain存放规则链信息,如规则链的模式2规则引擎规则链节点rule_node存放规则节点信息,如节点的配置信息3规则引擎规则链节点状态rule_node_state存放规则节点的状态数据4设备实体设备信息device存放设备基本信息,如设备配置文件、固件及软件版本5设备实体设备鉴权device_credentials存放设备鉴权信息,如鉴权类型、鉴权号码6设备实体设备配置device_profile存放设备配置文件数据,如设备的图标、配置详情信息7资产实体资产信息asset存放资产信息数据,如资产的类型、资产的描述8租户实体租户信息tenant存放租户数据,如租户的地址、电话信息9租户实体租户配置tenant_profile存放租户数据,如租户的地址、电话信息,租户的租用能力10客户实体客户信息customer存放客户数据,如客户的详细地址、所归属的租户11用户实体用户信息tb_user存放软件用户信息,如用户所属的客户及租户12用户实体用户鉴权user_credentials存放软件用户鉴权信息,如用户的用户名、密码,重置令牌13告警实体告警信息alarm存放软件告警信息,如告警信息的程度、处理状态14OTA实体空中下载升级包信息ota_package存放设备升级软件包的信息,如软件的版本、文件名、校验码15仪表盘实体用户信息dashboard存放软件看板信息,如看板的配置、分配客户的信息16属性实体属性信息attribute_kv存放属性键值对信息,如属性的类型、属性值17遥测实体遥测信息tb_kv存放遥测键值对数据,如遥测的键及其值18遥测实体最新遥测信息tb_kv_latest存放最新的遥测键值对数据,如遥测的键及其值19遥测实体遥测字典tb_kv_dictiontry存放遥测键的字典数据20组件组件描述component_descriptor存放规则引擎组件的描述信息,如配置数据21部件部件类型widget_type存放部件信息22部件部件库widget_bundle存放部件库信息,相当于将部件归类23审计审计日志信息aduit_log存放审计日志数据,如用户使用本软件的ip地址、浏览器信息、操作系统信息24OAuth2授权服务注册oauth2_registration存放授权注册信息,如访问令牌URI、授权用户信息25OAuth2授权服务注册oauth2_client_registration_template存放客户端注册信息模板,如GitHub的授权信息所需配置项、Apple的授权信息所需的配置项26OAuth2授权服务注册oauth2_params存放授权用户信息,如租户信息27OAuth2移动端授权oauth2_mobile存放移动端授权登录信息,如应用包名、应用令牌28OAuth2授权域信息oauth2_domain存放授权域相关信息,如域名、域访问协议29OAuth2授权域信息oauth2_client_registration_info存放授权客户端注册相关信息,如域名、域访问协议30OAuth2授权域信息oauth2_client_registration存放授权域相关信息,如域名、域协议31边缘计算边缘计算edge存放边缘计算服务信息32边缘计算边缘计算事件edge_event存放边缘计算发生的事件数据,如事件信息33实体视图实体视图entity_view类似数据库的视图功能,存放视图信息,如分配视图的起止时间34资源资源resource存放资源数据信息,如秘钥文件信息35rpc远程过程调用rpc存放远程过程调用数据,如请求数据、响应数据36关系实体关系数据relation存放实体间的关系,如资产与资产的包含类型、起始实体类型数据37事件实体事件event存放各实体类事件的信息,如事件类型、事件数据38设置管理员设置admin_setting存放设置信息,如基本设置、邮件设置39接口接口状态api_usage_state存放接口使用信息,如各类展示卡片激活状态40版本版本设置tb_schema_settings存放软件版本信息2 遥测数据存放数据表2.1 分区表遥测数据存放表名为ts_kv,按照时间(月份)进行分区表设计,如下图所示。2.2 字段遥测的数据类型有五种,包括:public enum DataType { STRING, LONG, BOOLEAN, DOUBLE, JSON; }最新遥测数据保存表名为ts_kv_latest,当表达到预定行数值后将数据复制到表ts_kv中。2.3 压缩键名字段key是数值,在表ts_kv_dictionary有其对应关系,当遥测数据中含有相应的键名时,在ts_kv使用数字进行对应存储,可以节省磁盘空间。3 一些字段命名问题3.1 create_time字段必有大致看一下这40张表的字段,create_time字段的出现的频次极高,因为数据的创建时间对后期运维有很大参考价值。
本编博客综合多篇国内外博客1,2,3,筛选出共有的2022年要知悉的九大前沿科技,并在此基础上做一些引申,帮助读者们掌握现行流行的互联网相关的科学技术,通过趋势看未来,通过趋势看市场。或许某些技术已经在应用,或许某些技术正在来临。技术会带来社会的变革,会引起市场的波动。😃 关注前沿科技,与时代共脉搏。😃1. 网络安全(Cyber Security)凡事安全都是第一位的,网络安全也是互联网的一等公民,没有安全的网络环境,网民和企业的数据被随意窥探和窃取,势必造成混乱的网络环境,导致网络不可信。随着电子设备和传感器的增多,互联网上的数据也在迸发上涨,更加凸显网络安全的重要性。网络安全是一种对抗技术,用于阻止各种网络攻击,如DoS攻击、网络钓鱼、恶意软件、网络病毒等,以此来保护APP、用户和隐私数据的安全。两个前沿网络安全相关技术:虚拟分散网络区块链网络安全相关岗位在2022年也会成为炽手可热的香饽饽。2. 一切即服务(Everything-as-a-Service)我们已经熟悉IaaS、PaaS再到SaaS,从基础设施到软件都成为一种服务。未来,万物皆可成为一种服务即XaaS(Everything-as-a-Service)。一切即服务 (XaaS) 是一个云计算术语,表示出现了大量服务和应用程序,供用户通过网络按需访问,而不是通过本地方式使用。可以灵活地自定义计算环境,以按需打造所需的体验。 XaaS 已经扩展到包含许多服务,例如:Function-as-a-ServiceIT-as-a-ServiceSecurity-as-a-ServiceDatabase-as-a-ServiceX-as-a-Service随着应用程序变得更加便携,计算周期更容易实时获取,数据集成平台简化连接,供应商形成跨平台联盟,这种多云趋势将转为全云趋势。3. 人工智能(AI)人工智能技术包含很广泛,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等4。人工智能实施将提升项目的性能、可扩展性和可靠性,同时能有完整的投资回报。从市场来看,全球人工智能市场将从 2021 年的 583 亿美元增长到 2026 年的 3096 亿美元。年复合增长率为 39.7,人工智能领域的进步如此之大,公司投入数十亿美元,毫无疑问,人工智能就是未来。4. 5G网络(5G Network)5G网络的下行速度是20G bps,上行速度是10G bps,至少是4G网络的40倍只左右。这将为电信运营商打开新服务、网络运营和客户体验的大门。根据 GSM 协会的数据,到 2025 年,5G网络估计在全球拥有超过 17 亿用户。5G基础设施行业的一些主要参与者包括三星、华为、埃里克森、思科和诺基亚网络等。到 2026 年,全球 5G 服务市场预计将从 530 亿美元增加到 2492 亿美元。5G还将推动物联网和虚拟现实的重大进步。5. 虚拟现实和增强现实( VR & AR)创新技术提供更多身临其境的体验,如 AR 和 VR。 虚拟现实让用户沉浸在模拟环境中,增强现实是现实世界中的技术叠加。 思科预测,到 2022 年,全球所有娱乐领域的 AR-VR 流量将增长 12 倍。触觉让我们对视觉或听觉无法完全体验的事物有更深入的了解。这就是触觉虚拟现实发挥作用的地方。它结合了多种技术的使用,包括传感器、高级光学等,捆绑在一个设备中,将增强的数字内容叠加到实时空间。AR 和 VR 在培训、娱乐、教育、营销甚至受伤后康复方面具有巨大潜力,用于培训医生进行手术,为博物馆参观者提供更深入的体验,增强主题公园,甚至增强营销。2021年12月30日消息,美国脸书母公司Meta旗下的虚拟现实(VR)头戴装置Oculus在圣诞购物季热销,带动了该设备应用程序在苹果应用商店下载数量跻身前列,显示用户对新技术设备的青睐程度高涨。2019 年销售了 1400 万台 AR 和 VR 设备。预计到 2022 年全球 AR 和 VR 市场将增长到 2092 亿美元,只会在趋势技术中创造更多机会,并欢迎更多专业人士为这个改变游戏规则的领域做好准备。互联网数据资讯公司Trendforce估计,AR和VR的年化出货量将以38.8%的复合年增长率增长。6. 行为互联网(IoB)收集和使用数据来驱动行为被称为行为互联网(IoB,Internet of Behaviors ) 5。 一个例子是工业场所使用计算机视觉来确定员工是否遵守口罩协议,然后收集这些行为数据供组织分析,以影响人们在工作中遵守政府协议。IoB 可以从许多来源收集、组合和处理数据,包括:公共部门处理的公民数据商业客户数据政府机构社交媒体公共区域位置跟踪处理这些数据的技术日益复杂,使这一趋势得以发展。7. 大数据分析(Big Data Analysis)数据收集在全球范围内以前所未有的速度增加。大数据和分析允许使用前沿技术存储、处理、分析和理解大量数据。据国际数据公司称,到 2025 年,地球上的数据总量将达到 175 泽字节(ZB),2022 年大数据和商业分析解决方案的全球收入预计将达到 2600 亿美元。8. 智能流程自动化(IPA)机器人流程自动化(RPA,Robotic Process Automation )的基本思想是“任何可以自动化的东西都应该自动化”。再进一步——智能流程自动化(IPA,Intelligent Process Automation )。 简而言之,IPA 允许机器人从人工智能、大数据、机器学习的能力中受益,这意味着它们可以随着时间的推移学习和改进。9. 边缘计算(Edge Computing)云计算曾经是一种值得关注的新技术趋势,现在已经成为主流,主要参与者 AWS(亚马逊网络服务)、微软 Azure 和谷歌云平台主导了市场。国内是阿里云、腾讯云、华为云及百度云。随着越来越多的企业迁移到云解决方案,云计算的采用仍在增长。但这不再是新兴的技术趋势,边缘计算逐渐成为主流。随着组织处理的数据量不断增加,他们已经意识到云计算在某些情况下的缺点。边缘计算旨在帮助解决其中一些问题,以绕过云计算引起的延迟并将数据传送到数据中心进行处理。它可以存在于“边缘”,靠近需要进行计算的地方。出于这个原因,边缘计算可用于处理远程位置的时间敏感数据,与集中位置的连接有限或没有连接。在这些情况下,边缘计算可以充当迷你数据中心。随着物联网 (IoT) 设备使用的增加,边缘计算将会增加。到2022年,全球边缘计算市场预计将达到67.2亿美元。而这种新技术趋势只会增长,而不会减少,创造各种工作岗位,主要是为软件工程师。引申出来的量子计算也将成为未来的趋势。“量子计算”利用量子物理学的特性来执行传统机器无法实现的计算和模拟。量子计算不再只是一项研究实验,而是一种正在改变包括医学生物学和气候变化在内的多个行业面貌的工具。微软、谷歌、IBM 和英特尔等大公司都在竞相打造量子计算工具。再延伸一下就是卫星通信,空天地海一体化计算。
一、项目打包软件及脚本webpack@4.46.0脚本:直接借助vue-cli的服务进行打包,"scripts": { "build": "vue-cli-service build", },整个项目使用vue-cli3生成。二、项目开发依赖环境整个项目包含以下重量级依赖库,是打包后项目包文件庞大的根源。echarts图表jquery、layui(因为是旧的代码不改了)SVG js 操作库拉斐尔raphael时间库moment百度vue地图依赖包版本说明:"dependencies": { "@ant-design/icons": "^2.1.1", "ant-design-vue": "^1.7.8", "axios": "^0.24.0", "compression-webpack-plugin": "^4.0.0", "core-js": "^3.6.5", "echarts": "^5.2.2", "echarts-liquidfill": "^3.1.0", "element-resize-detector": "^1.2.3", "hammer": "^0.0.5", "jquery": "^3.6.0", "js-base64": "^3.7.2", "layui-src": "^2.6.8", "moment": "^2.29.1", "raphael": "^2.3.0", "vue": "^2.6.11", "vue-baidu-map": "^0.21.22", "vue-echarts": "^6.0.0", "vue-router": "^3.5.3", "vuex": "^3.6.2" },三、瘦身前其中chunk-vendors文件差不多2M,相当大。四、瘦身方法公共文件CDN按需引入必须用使用webpack插件忽略未使用的文件五、评价方法打包分析插件webpack-bundle-analyzer进行结果评价文件浏览器查看六、瘦身过程1. CDN引入在vue.config.js文件中编辑配置,externals指的是排除以下依赖包的打包。vue等依赖包是公共基础。注意引入后变量的使用,注意externals对象中值的书写规则,如ant-design-vue,必须使用小写的antd变量来引用。module.exports = { runtimeCompiler: true, lintOnSave: false, //是否开启eslint productionSourceMap: false, configureWebpack: { externals:{ vue: 'Vue', 'vuex':'Vuex', 'vue-router': 'VueRouter', axios: 'axios', raphael: 'Raphael', 'ant-design-vue': 'antd', }, }, }在public/index.html文件中引入文件, <link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.6.8/css/layui.css"> <link rel="stylesheet" href="'https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.8/dist/antd.min.css'"> <script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://www.layuicdn.com/layui-v2.6.8/layui.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/locale/zh-cn.js"></script> <script src="https://cdn.jsdelivr.net/npm/ant-design-vue@1.7.8/dist/antd.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/raphael/2.3.0/raphael.js"></script>2. antd图标库的压缩在vue.config.js文件中编辑如下配置,将所需的文件指向另一个文件。 configureWebpack: { resolve:{ alias: { '@ant-design/icons/lib/dist$': path.resolve(__dirname,'./src/tools/icons.js') // 自建的文件的相对路径 } }, },icons.js文件内容如下,export { SettingOutline, CloudOutline, HomeOutline, FileImageOutline, SearchOutline, MenuFoldOutline, MenuUnfoldOutline, AppstoreOutline, ClusterOutline} from '@ant-design/icons'3. echarts图表库按需引入如果按照下述导入全部图表库是多余且占内存的,import * as echarts from 'echarts';在项目中只需要将需要的图标类型及组件依赖库引入即可,import echarts from 'echarts/lib/echarts';//导入主库 //导入用到的图表类型 import 'echarts/lib/chart/line'; import 'echarts/lib/chart/bar'; import 'echarts/lib/chart/pie'; //导入用到的图表组件,如网格、数据集、标题等 import 'echarts/lib/component/tooltip'; import 'echarts/lib/component/legend'; import 'echarts/lib/component/title'; import 'echarts/lib/component/dataset'; import 'echarts/lib/component/grid';注意上述的图表组件库需要导入,不导入会导致图表渲染失败。4. 百度地图百度地图的依赖包很大,因此更加需要按需引入,如下所示。import BaiduMap from 'vue-baidu-map/components/map/Map.vue' import BmScale from 'vue-baidu-map/components/controls/Scale' import BmNavigation from 'vue-baidu-map/components/controls/Navigation' import BmMarker from 'vue-baidu-map/components/overlays/Marker' import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow'5. 插件式过略掉moment/locale下的文件, configureWebpack: { plugins:[ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), ], },七、瘦身结果文件浏览器中可看到,
笔者在前段时间使用LayUI开发了一款编解码工具,现在项目中使用的是Vue,因此希望在新项目中整合该工具。因此就涉及到Vue项目如何使用LayUI的问题。1,安装LayUI开发包因为LayUI依赖jquery,因此需要同步安装。npm i jquery npm i layui-src2,导入LayUI开发包在需要整合工具的View组件里导入依赖。import 'jquery/dist/jquery.min' import 'layui-src/dist/css/layui.css' import 'layui-src/dist/layui.js'这种导入方式和直接在link标签里导入是一致的。3,在挂载函数mounted中加载LayUI组件当DOM元素被渲染完毕后,才能够使用,因此需要在mounted()函数里加载需要用到的LayUI的组件 layui.use(['element', 'layer','form','laydate','table'], function(){your code area})4,解决加载LayUI日期组件出现的错误在编解码工具中使用了日期组件,但是点击无反应,且控制台报下述错误。layui error hint: http://localhost:8080/js/css/modules/laydate/default/laydate.css?v=5.3.1 timeout字面意义就是请求该路径超时,查询该路径是无效的,因此重新引入该模块的CSS文件即可,即将该文件import进来。import 'layui-src/dist/css/modules/laydate/default/laydate.css'这家伙又出现了 😃5,整合后的界面界面元素还是原来的样式,其实可以使用antd-vue进行进一步统一。
一、问题描述组件的层级关系如图所示,期望是点击气象设备组件的解析按钮将文本框的数据解析为气象对象(包含经纬度信息),并将该值传递给地图子组件,地图组件根据其经纬度信息更新位置锚点。数据传递的方式采用对象动态绑定,即将所有的属性值进行向下单向传递。<DisplayMap v-bind:meteorologyVo="meteorologyVo"></DisplayMap>地图子组件利用props进行引用:props:{ meteorologyVo: Object, }锚点的HTML代码为:<bm-marker :position="{lng: meteorologyData.longitude, lat: meteorologyData.latitude}"></bm-marker>绑定后,点击解析按钮,地图子组件的锚点跑到了经纬度同为0的地方。二、问题分析有两个层次的问题需要搞清楚:对象是通过引用传递到子组件中,对象的属性值发生变化,引用未发生变化,导致Vue实例监听不到变化组件的层次过深,地图子组件不是真实的子组件,图中还经历了行组件ARow三、曲线解决问题3.1 添加动态聚合标签<bm-marker-clusterer :averageCenter="true"> <bm-marker v-for="marker of markers" :key="marker.code" :position="{lng: marker.lng, lat: marker.lat}" @click="lookDetail(marker)" animation="BMAP_ANIMATION_BOUNCE"></bm-marker> </bm-marker-clusterer>3.2 添加数组对象markersdata(){ markers: [], }3.3 添加对象监听函数曲线救国,利用数组的操作更新视图,数组的多种方法都可以让Vue实例对DOM进行重新渲染。watch:{ meteorologyVo:/* 监听该对象的变化进行回调 */{ handler(val, oldValue){ console.log(oldValue); let marker = { code: 2, lng: val.gpsVo.longitude, lat: val.gpsVo.latitude, } this.markers.pop(); this.markers.push(marker); }, deep: true }四、结果展示五、方案优化由于初步接触Vue.js,对其父组件传值给子组件的规范不太熟悉,官方如是说:我原来的子组件中动态绑定的属性名称如下:<DisplayMap v-bind:meteorologyVo="meteorologyVo"></DisplayMap>属性值引用如下:props:{ meteorologyVo: Object, },因此,将子组件中动态绑定的属性名称按照规范修改如下:<DisplayMap1 v-bind:child-meteorology="meteorologyVo"></DisplayMap1>属性值引用如下:props:{ childMeteorology: { type: Object, default: function(){ return {}; }, required: true } },但是watch函数仍旧因为需求要用,当父组件的对象值改变后,地图的居中需要以锚点的坐标。而且,我们还可以知道,Vue底层实现的原来,应该是实例化子组件时候监听了父组件的对象,逻辑使用对象代理来完成通知。
一,类加载器基础巩固类加载器是JVM的重要核心组件之一,也是字节码执行的发源地,只有准确加载了类,JVM才能够创建对象。一般地有三种类加载器,其名称、对应的对象类以及作用分别是(以JDK8为例):启动类加载器——加载JRE库文件用于加载rt.jar等11份文件,如下图所示,扩展类加载器——加载JRE扩展文件用于加载dnsns.jar等12份文件,如下图所示,系统类加载器——加载类路径(classPath)下的所有文件后两种类加载器均是sun.misc.Launcherd的内部嵌套静态类且继承了java.net包中的URLClassLoader类,启动类使用的加载器为null。二,使用场景1.对类进行动态地加载、使用和卸载常用在Web系统中对编解码器的开发,将编解码器按照一定规则编写好后打包成外部jar包,上传到系统平台中,通过类加载器对jar包的加载完成编解码对象的生成,进而使用其编解码方法。不需要重新编译整个系统程序,完成代码的局部更新;2.自定义类加载器通过自定义类加载器,三,打包一个jar3.1 功能把字符串解码为新格式的字符串3.2 解码接口public interface DecodeToPOJO { Object decode(String hexContent); }3.3 解码接口实现类public class Decoder implements DecodeToPOJO { @Override public Object decode(String hexContent) { return "say Hi"; } public static void main(String[] args) { Decoder decoder = new Decoder(); System.out.println(decoder.decode("")); } }3.4 目的在HTTP GET接口中通过加载jar包的形式调用Decoder类的decode方法。3.5 生成jar包四,编写一个接口加载类 @RequestMapping("/doClassLoad") public String doClassLoad() throws IOException { long start = System.currentTimeMillis(); ClassLoader classLoader = JarClassLoader.loadJarToSystemClassLoader(new File("F:\\respository\\MessageTransformer\\out")); Class aClass = null; try { aClass = classLoader.loadClass("org.leobit.codec.Decoder"); System.out.println(aClass.hashCode()); } catch (Exception e) { e.printStackTrace(); } long end = System.currentTimeMillis(); return Long.toString(end - start); }JarClassLoader类在cn.hutool.hutool-core包中,省的自己编写了。<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>4.4.0</version> </dependency>五,源码分析我们主要关注加载类方法。aClass = classLoader.loadClass("org.leobit.codec.Decoder");进入该方法,可以看到该方法是线程安全的,首选检查类是否被加载,未加载的选择合适的类加载器进行加载,这就是双亲委派机制, protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }重点看findClass方法,实现类是URLClassLoader,findClass方法后的sun.misc.PerfCounter表示性能计数器,可以看到生成类对象后,对象类计数加1。protected Class<?> findClass(final String name) throws ClassNotFoundException { final Class<?> result; try { result = AccessController.doPrivileged( new PrivilegedExceptionAction<Class<?>>() { public Class<?> run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); Resource res = ucp.getResource(path, false); if (res != null) { try { return defineClass(name, res); } catch (IOException e) { throw new ClassNotFoundException(name, e); } } else { return null; } } }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } if (result == null) { throw new ClassNotFoundException(name); } return result; } 在来看defineClass方法,就是最终的生成对象的方法。 private Class<?> defineClass(String name, Resource res) throws IOException { long t0 = System.nanoTime(); int i = name.lastIndexOf('.'); URL url = res.getCodeSourceURL(); if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. Manifest man = res.getManifest(); definePackageInternal(pkgname, man, url); } // Now read the class bytes and define the class java.nio.ByteBuffer bb = res.getByteBuffer(); if (bb != null) { // Use (direct) ByteBuffer: CodeSigner[] signers = res.getCodeSigners(); CodeSource cs = new CodeSource(url, signers); sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); return defineClass(name, bb, cs); } else { byte[] b = res.getBytes(); // must read certificates AFTER reading bytes. CodeSigner[] signers = res.getCodeSigners(); CodeSource cs = new CodeSource(url, signers); sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0); return defineClass(name, b, 0, b.length, cs); } }一直重载定义类的方法,最后终于在defineClass1Native方法中创建出对象。可以看到就是将文件流读入到虚拟机中进行对象类的创建,该过程又包含class文件的校验、类变量的准备、方法的解析和初始化的阶段。六,加载jar包结果展示我们请求第4节中编写的接口,打印每次加载类的哈希码。可以看到通过同一类加载器加载的对象的哈希码是相同的。
Thingsboard支持的协议有:MQTTCOAPHTTP1 下载使用git进行下载Thingsboard最新源码git clone git@github.com:thingsboard/thingsboard.git2 软件环境及版本2.1 系统环境OS:Windows10JDK:OpenJDK11(必须使用该版本,其它容易出错误)从其镜像的Docker命令中可以看到其运行的版本/bin/sh -c ln -svT "/usr/lib/jvm/java-11-openjdk-$(dpkg --print-architecture)" /docker-java-home2.2 数据库环境Postgresql:11(默认用户名为:postgres,密码为:postgres)附安装链接,操作系统对应的Postgresql版本各不相同,请下载相应版本。安装完成后,创建数据库thingsboard。2.3 前端环境ndoe:v14.15.5yarn:1.22.102.4 编译环境Maven:3.6.32.5 应用环境Thingsboard:3.3.2-SNAPSHOT3 编译对于刚下载的源码直接跳过监测进行安装即可mvn install -DskipTests安装时间稍长,笔者用了约12mins,耐心等待即可。编译完成后的文件结构为:详细目录树状结构为:├─conf 项目配置文件 │ ├─i18n │ └─templates ├─data 项目数据文件,内含规则链相关数据库数据,执行安装时会用到 │ ├─cassandra │ ├─certs │ │ └─azure │ ├─json │ │ ├─demo │ │ │ └─dashboards │ │ ├─system 系统文件夹 │ │ │ ├─oauth2_config_templates │ │ │ └─widget_bundles │ │ └─tenant 租户文件夹 │ │ ├─device_profile │ │ ├─edge_management │ │ │ └─rule_chains │ │ └─rule_chains │ ├─sql postgresql数据库文件,初始化数据库使用 │ └─upgrade postgresql数据库文件,升级数据库使用(笔者还没体验过) │ ├─1.3.0 │ ├─1.3.1 │ ├─1.4.0 │ ├─2.0.0 │ ├─2.1.1 │ ├─2.1.2 │ ├─2.2.0 │ ├─2.3.1 │ ├─2.4.0 │ ├─2.4.2 │ ├─2.4.3 │ ├─3.0.1 │ ├─3.1.0 │ ├─3.1.1 │ ├─3.2.1 │ └─3.2.2 ├─install 安装项目时日志配置文件 ├─lib 项目jar包 └─logs 各种日志文件4 运行1.双击上图中序号为1的批处理文件,执行Thingsboard软件的安装及数据库的初始化,本质就是将thingsboard.exe其注册为一个服务,详细指令如下所示。@ECHO OFF setlocal ENABLEEXTENSIONS @ECHO Detecting Java version installed. :CHECK_JAVA for /f tokens^=2-5^ delims^=.-_^" %%j in ('java -fullversion 2^>^&1') do set "jver=%%j%%k" @ECHO CurrentVersion %jver% if %jver% NEQ 110 GOTO JAVA_NOT_INSTALLED :JAVA_INSTALLED @ECHO Java 11 found! @ECHO Installing thingsboard ... SET loadDemo=false if "%1" == "--loadDemo" ( SET loadDemo=true ) SET BASE=%~dp0 SET LOADER_PATH=%BASE%\conf,%BASE%\extensions SET SQL_DATA_FOLDER=%BASE%\data\sql SET jarfile=%BASE%\lib\thingsboard.jar SET installDir=%BASE%\data PUSHD "%BASE%\conf" java -cp "%jarfile%" -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication^ -Dinstall.data_dir="%installDir%"^ -Dinstall.load_demo=%loadDemo%^ -Dspring.jpa.hibernate.ddl-auto=none^ -Dinstall.upgrade=false^ -Dlogging.config="%BASE%\install\logback.xml"^ org.springframework.boot.loader.PropertiesLauncher if errorlevel 1 ( @echo ThingsBoard installation failed! POPD exit /b %errorlevel% ) POPD "%BASE%"thingsboard.exe install @ECHO ThingsBoard installed successfully! GOTO END :JAVA_NOT_INSTALLED @ECHO Java 11 is not installed. Only Java 11 is supported @ECHO Please go to https://adoptopenjdk.net/index.html and install Java 11. Then retry installation. PAUSE GOTO END :END 数据库结果为:共计40个表2. 上图中序号为3的批处理文件作用是将服务删除,但是数据库没有删掉,所以要想再次安装程序时,需要将数据库删掉,否则会报错。3. 通过命令行启动服务时,发现出错,如下图所示,原因是找不到类路径。(TODO:后续解决)因此就是用java命令进行运行,去掉不能识别的参数-Dinstall.data_dir=F:\respository\thingsboard\application\target\thingsboard-windows\thingsboard\data,命令是:java -Dplatform=windows -Xlog:gc*,heap*,age*,safepoint=debug:file=F:\respository\thingsboard\application\target\thingsboard-windows\thingsboard\logs\gc.log:time,uptime,level,tags:filecount=10,filesize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10 -Xms512m -Xmx1024m -jar F:\respository\thingsboard\application\target\thingsboard-windows\thingsboard\lib\thingsboard.jar运行日志部分为;2021-09-30 17:21:13.524 INFO 41488 --- [ main] o.t.s.a.service.DefaultActorService : Initializing actor system. 2021-09-30 17:21:13.576 INFO 41488 --- [ main] o.t.s.a.service.DefaultActorService : Actor system initialized. 2021-09-30 17:21:13.976 INFO 41488 --- [ main] o.t.s.c.t.adaptor.JsonConverterConfig : JSON type cast enabled = true 2021-09-30 17:21:13.977 INFO 41488 --- [ main] o.t.s.c.t.adaptor.JsonConverterConfig : JSON max string value length = 0 2021-09-30 17:21:14.059 INFO 41488 --- [ main] o.t.s.t.mqtt.MqttTransportService : Setting resource leak detector level to DISABLED 2021-09-30 17:21:14.060 INFO 41488 --- [ main] o.t.s.t.mqtt.MqttTransportService : Starting MQTT transport... 2021-09-30 17:21:15.141 INFO 41488 --- [ main] o.t.s.t.mqtt.MqttTransportService : Mqtt transport started! 2021-09-30 17:21:15.197 INFO 41488 --- [ main] o.e.c.core.network.RandomTokenGenerator : using tokens of 8 bytes in length 2021-09-30 17:21:15.217 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : coap CoapEndpoint uses udp plain 2021-09-30 17:21:15.229 INFO 41488 --- [ main] o.e.c.core.network.stack.BlockwiseLayer : BlockwiseLayer uses MAX_MESSAGE_SIZE=1024, PREFERRED_BLOCK_SIZE=1024, BLOCKWISE_STATUS_LIFETIME=300000, MAX_RESOURCE_BODY_SIZE=268435456, BLOCKWISE_STRICT_BLOCK2_OPTION=true 2021-09-30 17:21:15.233 INFO 41488 --- [ main] o.e.c.c.network.stack.ReliabilityLayer : ReliabilityLayer uses ACK_TIMEOUT=2000, ACK_RANDOM_FACTOR=1.5, and ACK_TIMEOUT_SCALE=2.0 as default 2021-09-30 17:21:15.239 INFO 41488 --- [ main] org.eclipse.californium.core.CoapServer : Starting server 2021-09-30 17:21:15.254 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector starts up 8 sender threads and 8 receiver threads 2021-09-30 17:21:15.260 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector listening on 0.0.0.0/0.0.0.0:5683, recv buf = 65536, send buf = 65536, recv packet size = 2048 2021-09-30 17:21:15.260 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : coap Started endpoint at coap://0.0.0.0:5683 2021-09-30 17:21:15.282 INFO 41488 --- [ main] o.t.s.t.coap.CoapTransportService : Starting CoAP transport... 2021-09-30 17:21:15.290 INFO 41488 --- [ main] o.t.s.t.coap.CoapTransportService : CoAP transport started! 2021-09-30 17:21:15.454 INFO 41488 --- [ main] t.s.t.l.b.LwM2MTransportBootstrapService : Starting LwM2M transport bootstrap server... 2021-09-30 17:21:16.004 INFO 41488 --- [ main] o.e.c.core.network.RandomTokenGenerator : using tokens of 8 bytes in length 2021-09-30 17:21:16.005 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M BS Server-coap://] CoapEndpoint uses udp plain 2021-09-30 17:21:16.007 INFO 41488 --- [ main] o.e.c.core.network.stack.BlockwiseLayer : BlockwiseLayer uses MAX_MESSAGE_SIZE=1024, PREFERRED_BLOCK_SIZE=1024, BLOCKWISE_STATUS_LIFETIME=300000, MAX_RESOURCE_BODY_SIZE=268435456, BLOCKWISE_STRICT_BLOCK2_OPTION=true 2021-09-30 17:21:16.007 INFO 41488 --- [ main] o.e.c.c.network.stack.ReliabilityLayer : ReliabilityLayer uses ACK_TIMEOUT=2000, ACK_RANDOM_FACTOR=1.5, and ACK_TIMEOUT_SCALE=2.0 as default 2021-09-30 17:21:16.036 INFO 41488 --- [ main] o.e.c.s.dtls.InMemoryConnectionStore : Created new InMemoryConnectionStore [capacity: 150000, connection expiration threshold: 600s] 2021-09-30 17:21:16.040 INFO 41488 --- [ main] o.e.c.core.network.RandomTokenGenerator : using tokens of 8 bytes in length 2021-09-30 17:21:16.040 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M BS Server-coaps://] CoapEndpoint uses lwm2m correlation 2021-09-30 17:21:16.041 INFO 41488 --- [ main] o.e.c.core.network.stack.BlockwiseLayer : BlockwiseLayer uses MAX_MESSAGE_SIZE=1024, PREFERRED_BLOCK_SIZE=1024, BLOCKWISE_STATUS_LIFETIME=300000, MAX_RESOURCE_BODY_SIZE=268435456, BLOCKWISE_STRICT_BLOCK2_OPTION=true 2021-09-30 17:21:16.041 INFO 41488 --- [ main] o.e.c.c.network.stack.ReliabilityLayer : ReliabilityLayer uses ACK_TIMEOUT=2000, ACK_RANDOM_FACTOR=1.5, and ACK_TIMEOUT_SCALE=2.0 as default 2021-09-30 17:21:16.057 INFO 41488 --- [ main] org.eclipse.californium.core.CoapServer : Starting server 2021-09-30 17:21:16.059 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector starts up 1 sender threads and 1 receiver threads 2021-09-30 17:21:16.059 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector listening on 0.0.0.0/0.0.0.0:5687, recv buf = 65536, send buf = 65536, recv packet size = 2048 2021-09-30 17:21:16.060 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M BS Server-coap://] Started endpoint at coap://0.0.0.0:5687 2021-09-30 17:21:16.706 INFO 41488 --- [ main] o.e.californium.scandium.DTLSConnector : multiple network interfaces, using smallest MTU [IPv4 1400, IPv6 1400] 2021-09-30 17:21:16.708 INFO 41488 --- [ main] o.e.californium.scandium.DTLSConnector : DTLSConnector listening on 0.0.0.0/0.0.0.0:5688, recv buf = 65536, send buf = 65536, recv packet size = 16490, MTU = IPv4 1400 / IPv6 1400 2021-09-30 17:21:16.708 INFO 41488 --- [.0/0.0.0.0:5688] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-0-0.0.0.0/0.0.0.0:5688] 2021-09-30 17:21:16.708 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M BS Server-coaps://] Started endpoint at coaps://0.0.0.0:5688 2021-09-30 17:21:16.708 INFO 41488 --- [.0/0.0.0.0:5688] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-2-0.0.0.0/0.0.0.0:5688] 2021-09-30 17:21:16.708 INFO 41488 --- [.0/0.0.0.0:5688] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-1-0.0.0.0/0.0.0.0:5688] 2021-09-30 17:21:16.708 INFO 41488 --- [.0/0.0.0.0:5688] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-3-0.0.0.0/0.0.0.0:5688] 2021-09-30 17:21:16.708 INFO 41488 --- [ main] o.e.l.s.c.b.LeshanBootstrapServer : Bootstrap server started at coap://0.0.0.0/0.0.0.0:5687 coaps://0.0.0.0/0.0.0.0:5688 2021-09-30 17:21:16.708 INFO 41488 --- [ main] t.s.t.l.b.LwM2MTransportBootstrapService : Started LwM2M transport bootstrap server. 2021-09-30 17:21:16.781 INFO 41488 --- [ main] o.e.c.core.network.RandomTokenGenerator : using tokens of 8 bytes in length 2021-09-30 17:21:16.781 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M Server-coap://] CoapEndpoint uses udp plain 2021-09-30 17:21:16.782 INFO 41488 --- [ main] o.e.c.core.network.stack.BlockwiseLayer : BlockwiseLayer uses MAX_MESSAGE_SIZE=1024, PREFERRED_BLOCK_SIZE=1024, BLOCKWISE_STATUS_LIFETIME=300000, MAX_RESOURCE_BODY_SIZE=268435456, BLOCKWISE_STRICT_BLOCK2_OPTION=true 2021-09-30 17:21:16.782 INFO 41488 --- [ main] o.e.c.c.network.stack.ReliabilityLayer : ReliabilityLayer uses ACK_TIMEOUT=2000, ACK_RANDOM_FACTOR=1.5, and ACK_TIMEOUT_SCALE=2.0 as default 2021-09-30 17:21:16.782 INFO 41488 --- [ main] o.e.c.s.dtls.InMemoryConnectionStore : Created new InMemoryConnectionStore [capacity: 150000, connection expiration threshold: 600s] 2021-09-30 17:21:16.783 INFO 41488 --- [ main] o.e.c.core.network.RandomTokenGenerator : using tokens of 8 bytes in length 2021-09-30 17:21:16.783 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M Server-coaps://] CoapEndpoint uses lwm2m correlation 2021-09-30 17:21:16.783 INFO 41488 --- [ main] o.e.c.core.network.stack.BlockwiseLayer : BlockwiseLayer uses MAX_MESSAGE_SIZE=1024, PREFERRED_BLOCK_SIZE=1024, BLOCKWISE_STATUS_LIFETIME=300000, MAX_RESOURCE_BODY_SIZE=268435456, BLOCKWISE_STRICT_BLOCK2_OPTION=true 2021-09-30 17:21:16.783 INFO 41488 --- [ main] o.e.c.c.network.stack.ReliabilityLayer : ReliabilityLayer uses ACK_TIMEOUT=2000, ACK_RANDOM_FACTOR=1.5, and ACK_TIMEOUT_SCALE=2.0 as default 2021-09-30 17:21:16.805 INFO 41488 --- [ main] o.t.s.t.l.s.DefaultLwM2mTransportService : Starting LwM2M transport server... 2021-09-30 17:21:16.809 INFO 41488 --- [ main] org.eclipse.californium.core.CoapServer : Starting server 2021-09-30 17:21:16.811 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector starts up 1 sender threads and 1 receiver threads 2021-09-30 17:21:16.812 INFO 41488 --- [ main] o.e.californium.elements.UDPConnector : UDPConnector listening on 0.0.0.0/0.0.0.0:5685, recv buf = 65536, send buf = 65536, recv packet size = 2048 2021-09-30 17:21:16.813 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M Server-coap://] Started endpoint at coap://0.0.0.0:5685 2021-09-30 17:21:16.813 INFO 41488 --- [ main] o.e.californium.scandium.DTLSConnector : multiple network interfaces, using smallest MTU [IPv4 1400, IPv6 1400] 2021-09-30 17:21:16.815 INFO 41488 --- [.0/0.0.0.0:5686] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-0-0.0.0.0/0.0.0.0:5686] 2021-09-30 17:21:16.815 INFO 41488 --- [.0/0.0.0.0:5686] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-3-0.0.0.0/0.0.0.0:5686] 2021-09-30 17:21:16.815 INFO 41488 --- [.0/0.0.0.0:5686] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-1-0.0.0.0/0.0.0.0:5686] 2021-09-30 17:21:16.815 INFO 41488 --- [.0/0.0.0.0:5686] o.e.californium.scandium.DTLSConnector : Starting worker thread [DTLS-Receiver-2-0.0.0.0/0.0.0.0:5686] 2021-09-30 17:21:16.815 INFO 41488 --- [ main] o.e.californium.scandium.DTLSConnector : DTLSConnector listening on 0.0.0.0/0.0.0.0:5686, recv buf = 65536, send buf = 65536, recv packet size = 16490, MTU = IPv4 1400 / IPv6 1400 2021-09-30 17:21:16.816 INFO 41488 --- [ main] o.e.c.core.network.CoapEndpoint : [LWM2M Server-coaps://] Started endpoint at coaps://0.0.0.0:5686 2021-09-30 17:21:16.816 INFO 41488 --- [ main] o.e.l.server.californium.LeshanServer : LWM2M server started at coap://0.0.0.0/0.0.0.0:5685 coaps://0.0.0.0/0.0.0.0:5686 2021-09-30 17:21:16.818 INFO 41488 --- [ main] o.t.s.t.l.s.DefaultLwM2mTransportService : Started LwM2M transport server. 2021-09-30 17:21:17.281 INFO 41488 --- [ main] o.t.s.t.s.service.SnmpTransportService : SNMP transport service initialized 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: zookeeper.version=3.5.5-390fe37ea45dee01bf87dc1c042b5e3dcce88653, built on 05/03/2019 12:07 GMT 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: host.name=host.docker.internal 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.version=11.0.12 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.vendor=Eclipse Foundation 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.home=D:\jdk11open 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.class.path=F:\respository\thingsboard\application\target\thingsboard-windows\thingsboard\lib\thingsboard.jar 2021-09-30 17:21:17.313 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.library.path=D:\jdk11open\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;D:\VMware\bin\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Git\cmd;D:\xshell7\;D:\mysql5.7.31\bin;D:\nodejs\;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Yarn\bin\;D:\curl-7.76.0-win64-mingw\bin;D:\mingw64\mingw64\bin;D:\python3.7.0;D:\python3.7.0\Scripts;D:\jdk11open\bin;D:\gradle-6.8.2\bin;D:\scala\bin;D:\sbt\bin;%KE_HOME\bin;C:\Program Files\Docker\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;D:\apache-maven-3.6.3\bin;C:\Users\86134\AppData\Local\Microsoft\WindowsApps;D:\bandzip7\;C:\Users\86134\AppData\Roaming\npm;C:\Users\86134\AppData\Local\gitkraken\bin;. 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.io.tmpdir=C:\Users\86134\AppData\Local\Temp\ 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: java.compiler=<NA> 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.name=Windows 10 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.arch=amd64 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.version=10.0 2021-09-30 17:21:17.314 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: user.name=张博康 2021-09-30 17:21:17.315 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: user.home=C:\Users\86134 2021-09-30 17:21:17.315 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: user.dir=C:\WINDOWS\system32 2021-09-30 17:21:17.315 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.memory.free=208MB 2021-09-30 17:21:17.315 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.memory.max=1024MB 2021-09-30 17:21:17.315 INFO 41488 --- [ main] o.t.s.q.e.EnvironmentLogService : ThingsBoard server environment: os.memory.total=512MB 2021-09-30 17:21:17.903 INFO 41488 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator' 2021-09-30 17:21:18.437 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/*.js'], [] 2021-09-30 17:21:18.437 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/*.css'], [] 2021-09-30 17:21:18.438 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/*.ico'], [] 2021-09-30 17:21:18.439 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/assets/**'], [] 2021-09-30 17:21:18.439 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/static/**'], [] 2021-09-30 17:21:18.687 INFO 41488 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3d1703f8, org.springframework.security.web.context.SecurityContextPersistenceFilter@55880c, org.springframework.security.web.header.HeaderWriterFilter@241861bc, org.springframework.web.filter.CorsFilter@48928b57, org.springframework.security.web.authentication.logout.LogoutFilter@2197990b, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@4973fb7d, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@34c3e307, org.thingsboard.server.service.security.auth.rest.RestLoginProcessingFilter@3986b9e9, org.thingsboard.server.service.security.auth.rest.RestPublicLoginProcessingFilter@6ddbbfbb, org.thingsboard.server.service.security.auth.jwt.JwtTokenAuthenticationProcessingFilter@2d492d46, org.thingsboard.server.service.security.auth.jwt.RefreshTokenProcessingFilter@4f629aa4, org.thingsboard.server.service.security.auth.jwt.JwtTokenAuthenticationProcessingFilter@f348e10, org.thingsboard.server.config.RateLimitProcessingFilter@22d47f09, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1ac9c3cc, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6cf47d05, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@7bb78381, org.springframework.security.web.session.SessionManagementFilter@2045a469, org.springframework.security.web.access.ExceptionTranslationFilter@74ee07e, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@36d8ddc5] 2021-09-30 17:21:18.757 INFO 41488 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler' 2021-09-30 17:21:19.378 INFO 41488 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [public/index.html] 2021-09-30 17:21:21.043 INFO 41488 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel 2021-09-30 17:21:21.043 INFO 41488 --- [ main] o.s.i.channel.PublishSubscribeChannel : Channel 'application.errorChannel' has 1 subscriber(s). 2021-09-30 17:21:21.043 INFO 41488 --- [ main] o.s.i.endpoint.EventDrivenConsumer : started bean '_org.springframework.integration.errorLogger' 2021-09-30 17:21:21.094 INFO 41488 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2021-09-30 17:21:21.095 INFO 41488 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed5 访问Thingsboard5.1 登录登录页面URL为:http://127.0.0.1:8080/login界面是:5.2 输入账户名及密码Thingsboard提供了一个系统管理员账号。用户名为:sysadmin@thingsboard.org密码为:sysadmin5.3 创建租户账号5.3.1 创建租户5.3.2 创建租户管理员5.4 租户登录5.5 导入规则引擎不导入,解析数据时出错。5.5.1 导入规则链5.5.2 选择规则链文件规则链如图所示:5.6 设备配置规则链详情为:5.7 MQTT测试使用工具MQTTX软件测试MQTT消息上传至Thingsboard平台。访问URL为:127.0.0.1:1883访问TOPIC为:v1/devices/me/telemetry在设备详情页中能看到上传的遥测数据表示上传成功。
1 错误背景由于前面的错误导致Redis命令事务项执行丢弃。2 在Java应用程序层报的是未处理的异常2021-09-18 08:55:25.005 ERROR 4812 --- [quartzScheduler_Worker-1] org.quartz.core.JobRunShell : Job redis.cn.example.com.core.schedue.quartz.RedisQuartzJob threw an unhandled Exception. org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: EXECABORT Transaction discarded because of previous errors.3 查看Redis log日志发现真正的错误一般情况下Redis log日志文件在Redis安装目录下,名为server_log.txt。根据时间戳,到安装Redis的目录中找到其log日志。发现是因为RDB文件读写错误导致的Redis异常。[3476] 18 Sep 08:50:20.005 * Background saving started by pid 4752 [3476] 18 Sep 08:50:20.107 # fork operation complete [3476] 18 Sep 08:50:20.107 * Background saving terminated with success [3476] 18 Sep 08:51:06.609 # Failed opening the RDB file init.bat (in server root dir C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp) for saving: Permission denied [3476] 18 Sep 08:55:21.001 * 10 changes in 300 seconds. Saving... [3476] 18 Sep 08:55:21.001 * Background saving started by pid 4264 [3476] 18 Sep 08:55:21.101 # fork operation complete [3476] 18 Sep 08:55:21.101 # Background saving error而Redis的文件夹权限没有问题,因此只能是路径问题了,可以看到此时RDB文件路径为C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp,而配置文件里的RDB文件路径为C:\MiddleSoftware\redis,可以通过下述命令查询。> 127.0.0.1@6379 connected! > config get dir dir C:\MiddleSoftware\redis证明RDB文件路径配置项被修改了。4 结果分析导致这种结果很大可能是因为Redis端口6379暴露在外网中,被别人篡改了配置文件。网上很多介绍如何利用Redis端口黑进别人的系统。5 解决方案解决该问题有以下几个步骤:1.修改配置文件中的 bind 参数为bind 127.0.0.12.保护模式更改为yesprotected-mode yes3.改为带密码访问requirepass password4.修改云服务器入站规则关闭6379端口的访问6 展望其实外网有很多暴露端口的中间件或网络程序,有的因为没有设置密码或者密码强度不大而被人黑进来篡改数据或者利用算力导致资源浪费或者破坏,因此有必要加强对端口的安全管理。Redis RDB文件是数据持久存储的一种方式,另一种方式是AOF,再次启动Redis时,服务会先从该文件中加载恢复数据。
Kafka作为业界优秀的消息中间件,很多知名公司都在使用。笔者用命令行敲了敲其主题、生产者和消费者的组件,使用起来很方面,但是界面操作是笔者更喜欢的把玩方式,直观易记。因此对比了量款Kafka的管理项目,分别是Kafka Manage、Kafka Eagle,最后选用炫酷的Kafka Eagle。1 安装环境JDK: 15OS: Windows10Kafka: kafka_2.11-2.4.0MySQL:5.72 下载 Kafka Eagle点击下载地址下载即可。3 配置 Kafka Eagle在项目里找到system-config.properties文件进行修改。具体修改内容如下,修改和不改的已经做了标注。###################################### # multi zookeeper & kafka cluster list # Settings prefixed with 'kafka.eagle.' will be deprecated, use 'efak.' instead ###################################### #更改为本机地址及端口 efak.zk.cluster.alias=cluster1 #cluster1.zk.list=tdn1:2181,tdn2:2181,tdn3:2181 #cluster2.zk.list=xdn10:2181,xdn11:2181,xdn12:2181 cluster1.zk.list=127.0.0.1:2181 ###################################### # zookeeper enable acl ###################################### #不用管 cluster1.zk.acl.enable=false cluster1.zk.acl.schema=digest cluster1.zk.acl.username=test cluster1.zk.acl.password=test123 ###################################### # broker size online list ###################################### cluster1.efak.broker.size=20 ###################################### # zk client thread limit ###################################### kafka.zk.limit.size=32 ###################################### # EFAK webui port ###################################### #修改成该端口没用,默认就是8048 efak.webui.port=8090 ###################################### # kafka jmx acl and ssl authenticate ###################################### #不用管 cluster1.efak.jmx.acl=false cluster1.efak.jmx.user=admin cluster1.efak.jmx.password=123456 cluster1.efak.jmx.ssl=false cluster1.efak.jmx.truststore.location=/data/ssl/certificates/kafka.truststore cluster1.efak.jmx.truststore.password=ke123456 ###################################### # kafka offset storage ###################################### #不用管 cluster1.efak.offset.storage=kafka cluster2.efak.offset.storage=zk ###################################### # kafka jmx uri ###################################### #修改kafka的JMX端口 cluster1.efak.jmx.uri=service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi ###################################### # kafka metrics, 15 days by default ###################################### efak.metrics.charts=true efak.metrics.retain=15 ###################################### # kafka sql topic records max ###################################### efak.sql.topic.records.max=5000 efak.sql.topic.preview.records.max=10 ###################################### # delete kafka topic token ###################################### efak.topic.token=keadmin ###################################### # kafka sasl authenticate ###################################### #不用管 cluster1.efak.sasl.enable=false cluster1.efak.sasl.protocol=SASL_PLAINTEXT cluster1.efak.sasl.mechanism=SCRAM-SHA-256 cluster1.efak.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="kafka" password="kafka-eagle"; cluster1.efak.sasl.client.id= cluster1.efak.blacklist.topics= cluster1.efak.sasl.cgroup.enable=false cluster1.efak.sasl.cgroup.topics= cluster2.efak.sasl.enable=false cluster2.efak.sasl.protocol=SASL_PLAINTEXT cluster2.efak.sasl.mechanism=PLAIN cluster2.efak.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-eagle"; cluster2.efak.sasl.client.id= cluster2.efak.blacklist.topics= cluster2.efak.sasl.cgroup.enable=false cluster2.efak.sasl.cgroup.topics= ###################################### # kafka ssl authenticate ###################################### #不用管 cluster3.efak.ssl.enable=false cluster3.efak.ssl.protocol=SSL cluster3.efak.ssl.truststore.location= cluster3.efak.ssl.truststore.password= cluster3.efak.ssl.keystore.location= cluster3.efak.ssl.keystore.password= cluster3.efak.ssl.key.password= cluster3.efak.ssl.endpoint.identification.algorithm=https cluster3.efak.blacklist.topics= cluster3.efak.ssl.cgroup.enable=false cluster3.efak.ssl.cgroup.topics= ###################################### # kafka sqlite jdbc driver address ###################################### #注释掉 # efak.driver=org.sqlite.JDBC # efak.url=jdbc:sqlite:/hadoop/kafka-eagle/db/ke.db # efak.username=root # efak.password=www.kafka-eagle.org ###################################### # kafka mysql jdbc driver address ###################################### #添加这些参数 useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC efak.driver=com.mysql.cj.jdbc.Driver efak.url=jdbc:mysql://127.0.0.1:3306/ke?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=UTC efak.username=root efak.password=password4 启动 Kafka Eagle进到项目/bin文件目录里启动 Kafka Eagle。在启动之前,先让zookeeper和kafka启动起来。在启动过程中会遇到以下问题。数据库问题Q :The server time zone value ‘?й???’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the ‘serverTimezone’ configuration property) to use a more specifc time zone value if you want to utilize time zone support.A:使用如下命令解决按照配置文件里的端口输入访问路径打不开网站经验证,修改端口无效,可能在代码里固定了,因此还是访问端口8048即可。5 Kafka Eagle炫酷大屏界面启动完毕,访问地址为 http://127.0.0.1:8048/,输入用户名及密码(admin/123456)即可登录。
1 使用的工具FileZilla,提供了FTP客户端和服务器端软件,分别安装即可。2 具体配置2.1 设置被动模式2.2 设置用户及权限3 配置阿里云安全组规则将步骤2.1中的两个端口在阿里云服务器上进行开放。4 测试利用FileZilla客户端对阿里云FTP服务器进行测试。
一、软件版本OS: Win10layui: 2.6.5浏览器:Chrome 90.0.4430.212(正式版本) (64 位)二、问题描述当在本地开发网页时,引用layui框架样式表和js,目录结构如下图所示。加载layui的日期控件时,出现如下图所示的界面。日期前进和后退的按钮变成了方框。三、解决思路1. 上开发者工具F12打开谷歌浏览器开发者工具,按照下图依次点击,能够看到出现问题的是lay.css样式表没有加载到字体图标。2. 定位错误位置点击任意一处错误提示地方,右侧Headers面板中发现加载字体图标的文件路径错误。直接跳过了项目所在的文件夹,到了项目的父级文件夹,而父级文件夹是桌面。因此加载不到图标字体。3. 修改图标加载的相对文件路径因此将lay.css样式表中字体图标出现的路径修改为当前文件夹——.即可。修改后的文件为:/** 图标字体 **/ @font-face { font-family: 'layui-icon'; src: url('./font/iconfont.eot?v=256'); src: url('./font/iconfont.eot?v=256#iefix') format('embedded-opentype'), url('./font/iconfont.woff2?v=256') format('woff2'), url('./font/iconfont.woff?v=256') format('woff'), url('./font/iconfont.ttf?v=256') format('truetype'), url('./font/iconfont.svg?v=256#layui-icon') format('svg'); }四、结果
一、软件环境操作系统Windows10软件开发IDEIDEA 2020.3.2Elasticsearch{ "name" : "", "cluster_name" : "elasticsearch", "cluster_uuid" : "g3XhWHTmR-KelMCIPcq9Rw", "version" : { "number" : "7.12.1", "build_flavor" : "unknown", "build_type" : "unknown", "build_hash" : "unknown", "build_date" : "unknown", "build_snapshot" : true, "lucene_version" : "8.8.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }JDKjava version "15.0.2" 2021-01-19 Java(TM) SE Runtime Environment (build 15.0.2+7-27) Java HotSpot(TM) 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)这是另外下载的JDK,因为在构建过程中发现JDK8和JDK11都会报错。这是我的笔记本里下载JDK环境,三者都有。其中环境变量中的PATH里添加了JDK8的bin目录,如下图所示。项目构建工具Gradle从Elasticsearch5.0开始,构建工具由Maven改为Gradle。------------------------------------------------------------ Gradle 7.0 ------------------------------------------------------------ Build time: 2021-04-09 22:27:31 UTC Revision: d5661e3f0e07a8caff705f1badf79fb5df8022c4 Kotlin: 1.4.31 Groovy: 3.0.7 Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020 JVM: 1.8.0_201 (Oracle Corporation 25.201-b09) OS: Windows 10 10.0 amd64操作系统的环境变量设置JDK版本为1.8,因此这里显示的JVM版本是1.8,但是在后面的构建过程中,在IDEA中会进行配置选择ES项目自定义的JDK,如上为1.15。1.Gradle配置的详细信息为:2.设置Gradle的国内源:在gradle安装目录下的init.d文件夹中添加init.gradle文件。init.gradle文件中添加如下代码:allprojects{ repositories { def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/nexus/content/groups/public' def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/nexus/content/repositories/jcenter' def GRADLE_LOCAL_RELEASE_URL = 'https://repo.gradle.org/gradle/libs-releases-local' def ALIYUN_SPRING_RELEASE_URL = 'https://maven.aliyun.com/repository/spring-plugin' all { ArtifactRepository repo -> if(repo instanceof MavenArtifactRepository){ def url = repo.url.toString() if (url.startsWith('https://repo1.maven.org/maven2')) { project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL." remove repo } if (url.startsWith('https://jcenter.bintray.com/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL." remove repo } if (url.startsWith('http://repo.spring.io/plugins-release')) { project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_SPRING_RELEASE_URL." remove repo } } } maven { url ALIYUN_REPOSITORY_URL } maven { url ALIYUN_JCENTER_URL } maven { url ALIYUN_SPRING_RELEASE_URL } maven { url GRADLE_LOCAL_RELEASE_URL } } }二、构建成功后的输出======================================= Elasticsearch Build Hamster says Hello! Gradle Version : 7.0 OS Info : Windows 10 10.0 (amd64) JDK Version : 15 (Oracle) JAVA_HOME : D:\jdk-15.0.2 Random Testing Seed : 5882B1EC97E88DA1 In FIPS 140 mode : false ======================================= BUILD SUCCESSFUL in 1m 27s BUILD SUCCESSFUL in 2s可以看到此时的JDK版本为1.15。三、导入ES项目代码Git方式下载到本地或者直接下载压缩包然后解压到本地即可。源代码文件目录如下图所示。使用IDEA直接打开项目的根目录即可。四、构建项目构建完成后的项目目录如下图所示。 所有的包依赖也下载了Gradle安装目录中的caches文件夹中,如下图所示。五、跑源码详细步骤1. 跑源码前的准备在源码根目录下新建文件夹eshome,将发行版中的config和modules文件夹复制过来。2. 找到程序主文件Elasticsearch文件路径为:elasticsearch-7.12.1\server\src\main\java\org\elasticsearch\bootstrap\Elasticsearch.java3. 点击运行按钮这一步会报错4. 编辑运行参数点击工具栏中执行文本框中的下拉菜单,点击Edit Configurations...按钮。弹出的运行配置界面如下图所示。5. 修改运行参数点击配置界面右上角的修改参数下拉菜单按钮。选择Add VM options。在新增的虚拟机参数输入框中新增下述代码。-Des.path.home=F:\respository\elasticsearch-7.12.1\eshome -Des.path.conf=F:\respository\elasticsearch-7.12.1\eshome\config -Xms1g -Xmx1g -Dlog4j2.disable.jmx=true -Djava.security.policy=F:\respository\elasticsearch-7.12.1\eshome\config\elasticsearch.policy6. 根据提示修改安全文件将提示的三处地方进行注释接即可。7. 运行修改好参数后,点击Apply按钮,接着点击运行按钮。运行成功后的控制台输出如图所示。输出的详细日志为D:\jdk-15.0.2\bin\java.exe -Des.path.home=F:\respository\elasticsearch-7.12.1\eshome -Des.path.conf=F:\respository\elasticsearch-7.12.1\eshome\config -Xms1g -Xmx1g -Dlog4j2.disable.jmx=true -Djava.security.policy=F:\respository\elasticsearch-7.12.1\eshome\config\elasticsearch.policy "-javaagent:D:\IntelliJ IDEA 2020.3.2\lib\idea_rt.jar=60827:D:\IntelliJ IDEA 2020.3.2\bin" -Dfile.encoding=UTF-8 -classpath F:\respository\elasticsearch-7.12.1\server\out\production\classes;F:\respository\elasticsearch-7.12.1\server\out\production\resources;F:\respository\elasticsearch-7.12.1\libs\x-content\out\production\classes;F:\respository\elasticsearch-7.12.1\libs\cli\out\production\classes;F:\respository\elasticsearch-7.12.1\libs\core\out\production\classes;F:\respository\elasticsearch-7.12.1\libs\secure-sm\out\production\classes;F:\respository\elasticsearch-7.12.1\libs\geo\out\production\classes;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-core\8.8.0\8e2212079fb5210de2d2bc4659c45d77b8a7621d\lucene-core-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-analyzers-common\8.8.0\e84afab753aba3872aba55a370926a9373942d0d\lucene-analyzers-common-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-backward-codecs\8.8.0\e13efc816c2677250f8a18da90bf1a3cb90e02a9\lucene-backward-codecs-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-grouping\8.8.0\38d560849363acb4f033ed967a0656cdcd75b776\lucene-grouping-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-highlighter\8.8.0\c4d1dca0147ff8ee64ee30c1824af04507c45131\lucene-highlighter-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-join\8.8.0\de35b7480e9d72fb677daf32fa7ac90ce192e738\lucene-join-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-memory\8.8.0\5523f18aefae46a37a928704c4d8bf5b6af108f3\lucene-memory-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-misc\8.8.0\2c0393fcc76c3738257fc223dd23a6565d506886\lucene-misc-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-queries\8.8.0\7ff67de8424a44ad47fb5b2688b025675ab36f9d\lucene-queries-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-queryparser\8.8.0\12c1fff58ee07ba310d8aad03a687e190487ea60\lucene-queryparser-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-sandbox\8.8.0\a75aefdd97af9590e04e8b2c82be04e37ad82162\lucene-sandbox-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-spatial-extras\8.8.0\d830e093a2e6b308a7bf7069e8d4b09cbf43963f\lucene-spatial-extras-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-spatial3d\8.8.0\4be2a3457e6113ef59606a24dc2cc210c67075e\lucene-spatial3d-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.lucene\lucene-suggest\8.8.0\2d5dcdad7e8b8284ddc0bad400e5633c12479e93\lucene-suggest-8.8.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.carrotsearch\hppc\0.8.1\ffc7ba8f289428b9508ab484b8001dea944ae603\hppc-0.8.1.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\joda-time\joda-time\2.10.4\8c10bb8815109067ce3c91a8e547b5a52e8a1c1a\joda-time-2.10.4.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.tdunning\t-digest\3.2\2ab94758b0276a8a26102adf8d528cf6d0567b9a\t-digest-3.2.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.hdrhistogram\HdrHistogram\2.1.9\e4631ce165eb400edecfa32e03d3f1be53dee754\HdrHistogram-2.1.9.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.locationtech.spatial4j\spatial4j\0.7\faa8ba85d503da4ab872d17ba8c00da0098ab2f2\spatial4j-0.7.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.locationtech.jts\jts-core\1.15.0\705981b7e25d05a76a3654e597dab6ba423eb79e\jts-core-1.15.0.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.1\268f0fe4df3eefe052b57c87ec48517d64fb2a10\log4j-api-2.11.1.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.11.1\592a48674c926b01a9a747c7831bcd82a9e6d6e4\log4j-core-2.11.1.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.elasticsearch\jna\5.7.0-1\8ffc051522e63292eaf757d89353c14e94233988\jna-5.7.0-1.jar;F:\respository\elasticsearch-7.12.1\libs\plugin-classloader\out\production\classes;D:\gradle-6.8.2\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.26\a78a8747147d2c5807683e76ec2b633e95c14fe9\snakeyaml-1.26.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.10.4\8796585e716440d6dd5128b30359932a9eb74d0d\jackson-core-2.10.4.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-smile\2.10.4\c872c2e224cfdcc5481037d477f5890f05c001b4\jackson-dataformat-smile-2.10.4.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-yaml\2.10.4\8a7f3c6b640bd89214807af6d8160b4b3b16af93\jackson-dataformat-yaml-2.10.4.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-cbor\2.10.4\c854bb2d46138198cb5d4aae86ef6c04b8bc1e70\jackson-dataformat-cbor-2.10.4.jar;D:\gradle-6.8.2\caches\modules-2\files-2.1\net.sf.jopt-simple\jopt-simple\5.0.2\98cafc6081d5632b61be2c9e60650b64ddbc637c\jopt-simple-5.0.2.jar org.elasticsearch.bootstrap.Elasticsearch [2021-05-11T10:33:12,072][INFO ][o.e.n.Node ] [] version[7.12.1], pid[5952], build[unknown/unknown/unknown/unknown], OS[Windows 10/10.0/amd64], JVM[Oracle Corporation/Java HotSpot(TM) 64-Bit Server VM/15.0.2/15.0.2+7-27] [2021-05-11T10:33:12,080][INFO ][o.e.n.Node ] [] JVM home [D:\jdk-15.0.2] [2021-05-11T10:33:12,087][INFO ][o.e.n.Node ] [] JVM arguments [-Des.path.home=F:\respository\elasticsearch-7.12.1\eshome, -Des.path.conf=F:\respository\elasticsearch-7.12.1\eshome\config, -Xms1g, -Xmx1g, -Dlog4j2.disable.jmx=true, -Djava.security.policy=F:\respository\elasticsearch-7.12.1\eshome\config\elasticsearch.policy, -javaagent:D:\IntelliJ IDEA 2020.3.2\lib\idea_rt.jar=60827:D:\IntelliJ IDEA 2020.3.2\bin, -Dfile.encoding=UTF-8] [2021-05-11T10:33:34,805][INFO ][o.e.p.PluginsService ] [] loaded module [aggs-matrix-stats] [2021-05-11T10:33:34,805][INFO ][o.e.p.PluginsService ] [] loaded module [analysis-common] [2021-05-11T10:33:34,805][INFO ][o.e.p.PluginsService ] [] loaded module [constant-keyword] [2021-05-11T10:33:34,805][INFO ][o.e.p.PluginsService ] [] loaded module [flattened] [2021-05-11T10:33:34,806][INFO ][o.e.p.PluginsService ] [] loaded module [frozen-indices] [2021-05-11T10:33:34,806][INFO ][o.e.p.PluginsService ] [] loaded module [ingest-common] [2021-05-11T10:33:34,806][INFO ][o.e.p.PluginsService ] [] loaded module [ingest-geoip] [2021-05-11T10:33:34,806][INFO ][o.e.p.PluginsService ] [] loaded module [ingest-user-agent] [2021-05-11T10:33:34,806][INFO ][o.e.p.PluginsService ] [] loaded module [kibana] [2021-05-11T10:33:34,807][INFO ][o.e.p.PluginsService ] [] loaded module [lang-expression] [2021-05-11T10:33:34,807][INFO ][o.e.p.PluginsService ] [] loaded module [lang-mustache] [2021-05-11T10:33:34,807][INFO ][o.e.p.PluginsService ] [] loaded module [lang-painless] [2021-05-11T10:33:34,808][INFO ][o.e.p.PluginsService ] [] loaded module [mapper-extras] [2021-05-11T10:33:34,808][INFO ][o.e.p.PluginsService ] [] loaded module [mapper-version] [2021-05-11T10:33:34,808][INFO ][o.e.p.PluginsService ] [] loaded module [parent-join] [2021-05-11T10:33:34,808][INFO ][o.e.p.PluginsService ] [] loaded module [percolator] [2021-05-11T10:33:34,808][INFO ][o.e.p.PluginsService ] [] loaded module [rank-eval] [2021-05-11T10:33:34,809][INFO ][o.e.p.PluginsService ] [] loaded module [reindex] [2021-05-11T10:33:34,809][INFO ][o.e.p.PluginsService ] [] loaded module [repositories-metering-api] [2021-05-11T10:33:34,809][INFO ][o.e.p.PluginsService ] [] loaded module [repository-encrypted] [2021-05-11T10:33:34,809][INFO ][o.e.p.PluginsService ] [] loaded module [repository-url] [2021-05-11T10:33:34,810][INFO ][o.e.p.PluginsService ] [] loaded module [search-business-rules] [2021-05-11T10:33:34,810][INFO ][o.e.p.PluginsService ] [] loaded module [searchable-snapshots] [2021-05-11T10:33:34,810][INFO ][o.e.p.PluginsService ] [] loaded module [snapshot-repo-test-kit] [2021-05-11T10:33:34,810][INFO ][o.e.p.PluginsService ] [] loaded module [spatial] [2021-05-11T10:33:34,811][INFO ][o.e.p.PluginsService ] [] loaded module [transform] [2021-05-11T10:33:34,811][INFO ][o.e.p.PluginsService ] [] loaded module [transport-netty4] [2021-05-11T10:33:34,811][INFO ][o.e.p.PluginsService ] [] loaded module [unsigned-long] [2021-05-11T10:33:34,811][INFO ][o.e.p.PluginsService ] [] loaded module [vectors] [2021-05-11T10:33:34,811][INFO ][o.e.p.PluginsService ] [] loaded module [wildcard] [2021-05-11T10:33:34,812][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-aggregate-metric] [2021-05-11T10:33:34,812][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-analytics] [2021-05-11T10:33:34,812][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-async] [2021-05-11T10:33:34,812][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-async-search] [2021-05-11T10:33:34,812][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-autoscaling] [2021-05-11T10:33:34,813][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-ccr] [2021-05-11T10:33:34,813][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-core] [2021-05-11T10:33:34,813][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-data-streams] [2021-05-11T10:33:34,813][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-deprecation] [2021-05-11T10:33:34,813][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-enrich] [2021-05-11T10:33:34,814][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-eql] [2021-05-11T10:33:34,814][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-fleet] [2021-05-11T10:33:34,814][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-graph] [2021-05-11T10:33:34,814][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-identity-provider] [2021-05-11T10:33:34,814][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-ilm] [2021-05-11T10:33:34,815][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-ingest] [2021-05-11T10:33:34,815][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-logstash] [2021-05-11T10:33:34,815][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-ml] [2021-05-11T10:33:34,815][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-monitoring] [2021-05-11T10:33:34,815][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-ql] [2021-05-11T10:33:34,816][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-rollup] [2021-05-11T10:33:34,816][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-runtime-fields] [2021-05-11T10:33:34,816][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-security] [2021-05-11T10:33:34,816][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-sql] [2021-05-11T10:33:34,816][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-stack] [2021-05-11T10:33:34,817][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-text-structure] [2021-05-11T10:33:34,817][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-voting-only-node] [2021-05-11T10:33:34,817][INFO ][o.e.p.PluginsService ] [] loaded module [x-pack-watcher] [2021-05-11T10:33:34,818][INFO ][o.e.p.PluginsService ] [] no plugins loaded [2021-05-11T10:33:35,388][INFO ][o.e.e.NodeEnvironment ] [] using [1] data paths, mounts [[工作 (F:)]], net usable_space [166.9gb], net total_space [172.6gb], types [NTFS] [2021-05-11T10:33:35,389][INFO ][o.e.e.NodeEnvironment ] [] heap size [1gb], compressed ordinary object pointers [true] [2021-05-11T10:33:35,473][INFO ][o.e.n.Node ] [] node name [], node ID [ktiYzgo8SX6bSW1j3nu7Sg], cluster name [elasticsearch], roles [transform, data_frozen, master, remote_cluster_client, data, ml, data_content, data_hot, data_warm, data_cold, ingest] [2021-05-11T10:33:35,675][INFO ][i.n.u.i.PlatformDependent] [] Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability. [2021-05-11T10:33:41,644][INFO ][o.e.x.m.p.l.CppLogMessageHandler] [] [controller/1352] [Main.cc@117] controller (64 bit): Version 7.12.1 (Build 4172997de5701c) Copyright (c) 2021 Elasticsearch BV [2021-05-11T10:33:42,265][INFO ][o.e.x.s.a.s.FileRolesStore] [] parsed [0] roles from file [F:\respository\elasticsearch-7.12.1\eshome\config\roles.yml] [2021-05-11T10:33:45,172][INFO ][i.n.u.i.PlatformDependent] [] Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability. [2021-05-11T10:33:45,216][INFO ][o.e.t.NettyAllocator ] [] creating NettyAllocator with the following configs: [name=unpooled, suggested_max_allocation_size=256kb, factors={es.unsafe.use_unpooled_allocator=null, g1gc_enabled=true, g1gc_region_size=1mb, heap_size=1gb}] [2021-05-11T10:33:45,308][INFO ][o.e.d.DiscoveryModule ] [] using discovery type [zen] and seed hosts providers [settings] [2021-05-11T10:33:46,079][INFO ][o.e.g.DanglingIndicesState] [] gateway.auto_import_dangling_indices is disabled, dangling indices will not be automatically detected or imported and must be managed manually [2021-05-11T10:33:46,962][INFO ][o.e.n.Node ] [] initialized [2021-05-11T10:33:46,962][INFO ][o.e.n.Node ] [] starting ... [2021-05-11T10:33:46,982][INFO ][o.e.x.s.c.f.PersistentCache] [] persistent cache index loaded [2021-05-11T10:33:47,276][INFO ][o.e.t.TransportService ] [] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300} [2021-05-11T10:33:47,611][WARN ][o.e.b.BootstrapChecks ] [] the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured [2021-05-11T10:33:47,613][INFO ][o.e.c.c.Coordinator ] [] cluster UUID [g3XhWHTmR-KelMCIPcq9Rw] [2021-05-11T10:33:47,625][INFO ][o.e.c.c.ClusterBootstrapService] [] no discovery configuration found, will perform best-effort cluster bootstrapping after [3s] unless existing master is discovered [2021-05-11T10:33:47,727][INFO ][o.e.c.s.MasterService ] [] elected-as-master ([1] nodes joined)[{ktiYzgo8SX6bSW1j3nu7Sg}{XQXm5W_DQVeRT31WKSdhPQ}{127.0.0.1}{127.0.0.1:9300}{cdfhilmrstw}{ml.machine_memory=16919429120, xpack.installed=true, transform.node=true, ml.max_open_jobs=20, ml.max_jvm_size=1073741824} elect leader, _BECOME_MASTER_TASK_, _FINISH_ELECTION_], term: 2, version: 37, delta: master node changed {previous [], current [{ktiYzgo8SX6bSW1j3nu7Sg}{XQXm5W_DQVeRT31WKSdhPQ}{127.0.0.1}{127.0.0.1:9300}{cdfhilmrstw}{ml.machine_memory=16919429120, xpack.installed=true, transform.node=true, ml.max_open_jobs=20, ml.max_jvm_size=1073741824}]} [2021-05-11T10:33:47,903][INFO ][o.e.c.s.ClusterApplierService] [] master node changed {previous [], current [{ktiYzgo8SX6bSW1j3nu7Sg}{XQXm5W_DQVeRT31WKSdhPQ}{127.0.0.1}{127.0.0.1:9300}{cdfhilmrstw}{ml.machine_memory=16919429120, xpack.installed=true, transform.node=true, ml.max_open_jobs=20, ml.max_jvm_size=1073741824}]}, term: 2, version: 37, reason: Publication{term=2, version=37} [2021-05-11T10:33:48,029][INFO ][o.e.h.AbstractHttpServerTransport] [] publish_address {127.0.0.1:9200}, bound_addresses {127.0.0.1:9200}, {[::1]:9200} [2021-05-11T10:33:48,030][INFO ][o.e.n.Node ] [] started [2021-05-11T10:33:48,389][INFO ][o.e.l.LicenseService ] [] license [ae30e2c3-34d9-414f-bab3-07c27ea4c0ab] mode [basic] - valid [2021-05-11T10:33:48,395][INFO ][o.e.x.s.s.SecurityStatusChangeListener] [] Active license is now [BASIC]; Security is disabled [2021-05-11T10:33:48,404][INFO ][o.e.g.GatewayService ] [] recovered [0] indices into cluster_state8. 在浏览器中输入验证在浏览器中输入http://127.0.0.1:9200/,就会显示出如下所示的响应结果。六、建议看看另一个搜索和分析引擎工具Splunk软件参见强烈推荐大数据软件Splunk,用于分析日志文件。能够像谷歌搜索一样使用。
功能需求所开发的软件内部状态需要进行监控,如当有服务不可用,即时通知系统维护人员监控告警消息。目前我们已基本离不开手机,因此能够通过手机收取消息可谓是方便之至。功能分析可选的方案有以下几种。邮箱方式企业微信钉钉机器人自开发手机移动APP因为邮箱经常收到很多垃圾信息,习惯屏蔽之。自开发手机移动APP所消耗的资源太大,而且功能较为单一。对比了企业微信和钉钉机器人的开发文档。选择了简单的钉钉机器人的实现方式。平时工作也是利用钉钉通知工作消息,因此算是锦上添花吧。功能实现自定义机器人接入开发文档链接在此。开发流程在文档里已经介绍的很详细了,不再赘述。原理就是利用HTTP POST请求钉钉服务器上该功能的微服务,钉钉也给开发者提供了SDK,能够快速上手完成业务功能开发。需要说明的是当前机器人尚不支持应答机制,该机制指的是群里成员在聊天@机器人的时候,钉钉回调指定的服务地址,即Outgoing机器人。消息类型支持文本 (text)、链接 (link)、Markdown(支持部分语法)、ActionCard、FeedCard。结果展示消息类型选择了钉钉提供的link方式。
1,通过桌面快捷方式设置需要开机自启动程序的快捷方式,应用场景如每次开机后自动打开word日志文档选中日志文档,点击鼠标右键按钮,点击发送到->桌面快捷方式Windows+R调出运行程序框在弹出的运行程序框中输入如下命令;shell:Common Startup此时弹出存放开机自启动时会调用的快捷方式程序链接的文件夹,将上一步产生的快捷方式剪切到该文件夹内即可;OK,等下次开机时会出自动打开该日志文档程序。2,通过注册服务方式可以借助Windows Service Wrapper小工具,将需要安装的程序转换为Windows服务。多个服务启动的顺序会有先后依赖,如Springboot启动依赖MySQL和Redis,因此开机自启动注册服务时,需要设置它们的依赖关系。3,终极武器——任务计划程序库可以任意定义何时何地执行脚本,强烈推荐,详情参见这篇博客Windows10系统设置定时任务 开机启动.bat文件。
选中某个数据库表,点击筛选按钮点击图中所框处选择按照哪个字段进行筛选点击图中所框处输入匹配的值点击应用按钮点击导出按钮,选择当前记录选择SQL脚本文件连续点击下一步即可完成SQL文件的生成,名字一般按照数据库表名生成的
0,使用意义在前后端开发过程中,需求过来,但是后端在开发的进程中,这时候前端想调用接口无法实现,因此需要用模拟服务器模拟出所要开发接口的属性(包括返回值,请求参数等),如果每个接口都要等后端开发完成再进行测试会很浪费时间,因此使用模拟接口来测试前端代码的功能,极大的缩短了等待时间,到后期后端全部开发出来接口再配合联调测试即可。1,创建Mock Server(模拟服务器)正如Postman程序中介绍的一样,模拟服务器允许模拟API站点,而不必设置后端。设置好站点API请求路径,接着输入预期的响应码和响应体完成创建即可。如果请求中需要带参数,直接点击下图中按钮,选中Request Body。2,设置请求方法名称下面以GET方法为例,填写请求方法为/hello,相应数据为{1,2,3,4},点击下一步。3,命名测试服务器填写好名称后,点击Create Mock Server按钮4,完成模拟服务器创建直接点击Close按钮完成模拟服务器的创建5,模拟服务器展示界面6,在浏览器中测试生成的路径在浏览器中输入生成的路径,可以看到返回的数据就是我们填写的响应体中的数据
前言网络服务器以Linux操作系统的居多,因其天然的底层框架优势。笔者因为项目需求要在Linux操作系统服务上部署Java web项目,手头上没有该操作系统的服务器,因此使用虚拟机技术虚拟出一台CentOS7.5的虚拟服务器,并以此为基础进行项目部署。笔者在学生阶段主要使用的是Windows系统,对Linux操作系统停留在认知的阶段,基本的命令会一点,就这样一步一步的走了出来,完成了Java web项目的成功部署。途中踩到的坑很多,记录下来,与各位分享。背景连接虚拟机会话如图所示。虚拟机的安装和连接在这里不再赘述。请参见这篇博客。多个依赖的中间件JDK1.8 (运行平台), 版本详情为:java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)MySQL5.7(持久存储),版本详情为:mysql Ver 14.14 Distrib 5.7.21, for linux-glibc2.12 (x86_64) using EditLine wrapperTomcat8.5 (网站服务器容器),版本详情为:Apache Tomcat/8.5.58Redis 采用最新版本即可(中间缓存),版本详情为:Redis server v=6.0.9 sha=00000000:0 malloc=libc bits=64 build=9c395f6f2c1461e4查询命令为:redis-server --version环境将所需的中间件软件压缩包通过命令rz上传至虚拟机中(本次测试文件路径为/usr/local/src)。因为MySQL太大了,占用内存,被我删除了。因为只有其余三个依赖包,如图所示。1.Java环境安装及配置首先检测一下系统安装了JDK吗?CentOS7.5系统自带OpenJDK,将其删除。详情参照在CentOS7.4中安装jdk的几种方法及配置环境变量。解压 -> 移动到指定文件夹下tar xzvf jdk-8u151-linux-x64.tar.gz mv jdk1.8.0_151 /usr/local/java配置环境变量(老套路了), 通过vim /etc/profile 打开文件,追加下列变量声明JAVA_HOME=/usr/local/java JRE_HOME=/usr/local/java/jre CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$JAVA_HOME/bin:$PATH export PATH JAVA_HOME CLASSPATH添加完后通过命令source /etc/profile使其生效2.Tomcat安装及配置解压 -> 移动到指定文件夹下tar xzvf apache-tomcat-8.5.58.tar.gz mv apache-tomcat-8.5 /usr/local/tomcat删除Tomcat中的webapps文件夹下的一系列文件如docs、examples、manager、ROOT、host-manager进行容器安全加固3.Redis安装及配置解压 -> 移动 -> 安装gcc依赖 -> 升级gcc -> 编译 ->配置详情参照在Linux下安装redis详细安装教程图文。在安装需要联网时,配置DNS为114.114.114.114 8.8.8.8接着对yum国内源进行更改。因为期间遇到需要连接外网的安装步骤,如下载gcc、升级gcc。否则,下载速度很慢或者获取资源超时。wget -P /etc/yum.repos.d http://mirrors.163.com/.help/CentOS7-Base-163.repo接着安装Rediscd /usr/local/src tar xzvf redis-6.0.9.tar.gz mv redis-6.0.9 /usr/local/redis #依赖安装 yum install gcc yum install gcc-c++ #升级 yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils scl enable devtoolset-9 bash #编译 make #创建文件夹 mkdir -p /usr/local/redis/bin mkdir -p /usr/local/redis/etc #复制文件 cp -aRp redis.conf /usr/local/redis/etc cp -aRp mkreleasdhdr.sh redis-benchmark redis-check-aof redis-cli redis-server /usr/local/redis/bin配置Redis通过命令打开文件vim /usr/local/redis/etc/redis.confdaemonize yes #(找到这一项,修改为yes) bind 192.168.225.128 127.0.0.1 #设置本机服务IP,应是内网IP。外网不安全启动redis-server /usr/local/redis/etc/redis.conf #用具体的文件路径来启动4.Mysql安装及配置解压 -> 移动 -> 查重 -> 配置cd /usr/local/src yum -y install numactl #解决安装过程中的报错 mv mysql-5.7.21-linux-glibc2.12-x86_64 /usr/local/mysql #创建文件夹 mkdir /usr/local/mysql/data #创建用户和组 groupadd mysql useradd -r -g mysql mysql #安装依赖包 yum install libaio #将安装目录所有者及所属组改为mysql chown -R mysql.mysql /usr/local/mysql #初始化 /usr/local/mysql/bin/mysqld --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data --initialize #记住生成的密码bwclBwti,1gh #编辑配置文件(重点对象) vim /etc/my.cnf [mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/usr/local/mysql/mysql.sock pid_file=/usr/local/mysql/mysql.pid log-error=/usr/local/mysql/data/mysqllog.err user=mysql [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid [client] port=3306 socket=/usr/local/mysql/mysql.sock default-character-set=utf8 #将mysql加入到服务中 cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql #开机启动 chkconfig mysql on #启动mysql service mysql start #配置环境变量 export MYSQL_HOME="/usr/local/mysql" export PATH="$PATH:$MYSQL_HOME/bin" #使能生效 source /etc/profile查重命令rpm -qa | grep mysql验证 mysql -u root -p更改初始化时产生的密码最后进行数据库创建,导入sql文件项目部署特别需要注意的是,要知道如何查看日志文件和关闭防火墙,在关闭防火墙时,也要注意版本的不同导致命令的不同。通过Maven方式将开发包打包成wwar包进行部署。如图所示,项目名(右键)-> Run As -> Maven build接着进入配置界面;在项目目录target文件夹下可以找到打包好的war包;看一下war包内容。笔者在打包时候采用Export -> war方式,导致war包目录不通进而导致资源访问不到,需要对资源进行放行。这个是Maven安装的war包目录。这个通过STS3导出功能进行导出的war包目录。资源被放在了WEB_INF文件夹下了。最后将war包放到tomcat/webapps下,启动Tomcat完成部署。
软件版本Python: 3.7.3OS: Win7Kivy: 1.11.1Kivy installation method:pipopencv: 4.1.2.30注意事项kivy安装基于特定的Python版本,否则报错,二者对应版本问题查看官网1更换Pycharm的国内pip源,相关方法可以参见2pip版本也会对kivy的安装有影响,建议直接升最高级,如果提示pip错误,应该使用https协议,直接添加s即可opencv用于摄像头模块使用,不安装会报错官方安装教程3具体步骤第一步:安装kivy第二步:安装kivy依赖第三步:测试kivy官方首页提供的代码from kivy.app import App from kivy.uix.button import Button class TestApp(App): def build(self): return Button(text='Hello World') TestApp().run()看一下效果总结可以说比较Linux上的命令行安装,这个来的更加简洁和有效。有关树莓派的安装请参见4。
准备部分硬件树莓派4B裸板16GSD卡TypeC 电源CSI摄像头(没有/dev/video0的解决办法参见此解决办法)PC机一台(Windows 7,用于远程树莓派)路由器(组建局域网)软件Rasbian Buster OS(Raspbian Buster with desktop and recommended software,必须新版)VNC远程连接软件(Windows自带的远程桌面连接比起这个很Low,强推这个,可以直接显示远程主机的视频)Thonny Python IDE(系统会自带)PCManFM(文件管理器,启动树莓派后,发现文件管理打不开,更新安装此软件即可)换源系统源(注意是Buster版本)PIP源正文部分(多步骤预警)步骤1:扩充文件系统运行raspi-config,在终端命令行中输入:$ sudo raspi-config选择第7个高级选项,接着点击A1 扩充文件系统重启树莓派$ sudo reboot查看扩充后的分区$ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 15G 4.3G 9.5G 32% / devtmpfs 404M 0 404M 0% /dev tmpfs 437M 0 437M 0% /dev/shm tmpfs 437M 6.0M 431M 2% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 437M 0 437M 0% /sys/fs/cgroup /dev/mmcblk0p1 253M 52M 201M 21% /boot tmpfs 88M 4.0K 88M 1% /run/user/1000OK,成功后进去下一步。步骤2:安装依赖2.1 更新所有包$ sudo apt-get update $ sudo apt-get upgrade2.2 安装开发工具 CMake用于配置OpenCV构建过程$ sudo apt-get install build-essential cmake pkg-config2.3 安装图片I/O包用于加载各种格式的图片$ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng-dev2.4 安装视频I/O包相应地用于加载各种格式的视频$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev $ sudo apt-get install libxvidcore-dev libx264-dev2.5 安装GTK开发库用于编译OpenCV 子模块highgui$ sudo apt-get install libfontconfig1-dev libcairo2-dev $ sudo apt-get install libgdk-pixbuf2.0-dev libpango1.0-dev $ sudo apt-get install libgtk2.0-dev libgtk-3-dev2.6 安装优化库用于优化矩阵操作$ sudo apt-get install libatlas-base-dev gfortran2.7 安装Python 3头文件用于使用绑定的Python编译OpenCV$ sudo apt-get install python3-dev成功后进入下一步。步骤3:创建Python虚拟环境3.1 安装虚拟环境管理工具virtualenvwrapper$ sudo pip install virtualenv virtualenvwrapper3.2 修改系统环境配置文件在文件后面追加# virtualenv and virtualenvwrapper export WORKON_HOME=$HOME/.virtualenvs export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 source /usr/local/bin/virtualenvwrapper.sh重新加载系统环境文件$ source ~/.bashrc3.3 创建Python虚拟环境取名字为cv$ mkvirtualenv cv -p python3步骤4:PIP方式安装OpenCV在虚拟环境下安装OpenCV4(cv)$ pip install opencv-contrib-python==4.1.0.25步骤5:测试OpenCV安装结果$ python >>> import cv2 >>> cv2.__version__ '4.1.0' >>>ok,恭喜OpenCV4成功安装。用例部分import cv2 #要更改自己的文件绝对路径 face_cascade = cv2.CascadeClassifier('/home/pi/Desktop/opencv-master/data/haarcascades/haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('/home/pi/Desktop/opencv-master/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml') #加载CSI摄像头,通过libv4l2 cap = cv2.VideoCapture(0) #OpenCV版本测试 (major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.') while cap.isOpened(): _, img = cap.read() #计算摄像头的FPS if int(major_ver) < 3 : fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) else : fps = cap.get(cv2.CAP_PROP_FPS) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.1, 4) for (x, y , w ,h) in faces: cv2.rectangle(img, (x,y), (x+w, y+h), (255, 0 , 0), 3) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex, ey ,ew, eh) in eyes: cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0, 255, 0), 5) font = cv2.FONT_HERSHEY_SIMPLEX text = 'FPS: '+ str(fps) #将FPS的值展现到视频帧中 img = cv2.putText(img, text,(10,50), font, 1, (0,255,255), 2, cv2.LINE_AA) # Display the output cv2.imshow('img', img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release()在虚拟环境中跑一下代码(cv) pi@raspberrypi:cd code (cv) pi@raspberrypi:~/code $ python eye_detection.py结果如图
问题还原购买了两套树莓派4B板子,拿过来就想用已经安装好操作系统的SD卡(这个卡是树莓派3B+)直接跑,等了半天,能看到树莓派电源指示灯红色常亮,系统状态灯闪了一下。感觉不妙,想着别是板子坏掉了,就拿来另一个进行跑,依旧如此。解决思路首先排除电源的问题,用的是Type-c供电,电源指示灯常亮,安卓手机充电线也可以拿来用,博主买的套装;两个板子同时坏的几率不大,因为在这个供货商买了几次,板子都是OK的;开始关注板子状态指示灯,因为也只有这个是能直接感官到的现象,跑到树莓派官网下载网站中看到明显的Recovery字眼,就着重看了下,说明树莓派4B启动失败是常见的问题;4.就按照指示,断电后将SD卡拔出来,然后插电,看到状态指示灯常闪,说明板子的EEPROM是OK的1;5.开始怀疑装的系统是否有问题?最新版的系统没有下载,因此不好确定是这个的原因,因此坐等下载新系统,吐槽百度云下载不是一般的慢,直接从官网下载比这个还慢;6.树莓派4B的板子于2019.06.28发布,与之而来的是新的操作系统——Buster(版本号),发布时间是2019.07.10;7.再观察自己的原来的操作系统是老古董了;8.Ok,重装新的操作系统后,就OK了。9.强烈建议——直接下载新版本操作系统安装,避免其它未知麻烦。结论全新一代的树莓派4B和以往的版本硬件上差别很大,新增硬件EEPROM替代了旧版本启动三步走desecondstage,这个阶段中GPU加载SD卡启动分区中的bootloader.bin文件,而新版树莓派4B的EEPROM启动时候会直接忽略掉此SD卡中的bootload.bin文件1,因而很有可能是EEPROM中包含的代码加载不了第三阶段的start.elf文件,因此而导致系统启动不了。
前言:该研究是基于海康威视网络设备SDK_V6.0.2.35(for Windows x64)的研究。设备网络SDK是基于设备私有网络通信协议开发的,为后端设备(嵌入式网络硬盘录像机、视频服务器)、前端设备(网络摄像机、网络球机、IP模块)等产品服务的配套模块,用于远程访问和控制设备软件的二次开发。我们这里针对HIKVISION红外网络摄像机(型号是DS-2CD3T45-I3 6mm)进行二次开发。在购买前海康官网->服务支持->下载->SDK开发中查找能够被二次开发的型号。名称属性操作系统64bit开发IDEIntellJ IDEAJDKjdk1.8第一节:下载SDK_V6.0.2.35(for Windows x64),解压后进入目录CH-HCNetSDKV6.0.2.35_build20190411_Win64\CH-HCNetSDKV6.0.2.35_build20190411_Win64\Demo示例\4- Java 开发示例\1-ClientDemo\ClientDemo-NetBeansPro中,导入该工程。第二节:导入后将图中所选中的两个jar包引入工程模块中。第三节阅读图中所示的文件,修改文件加载路径。在工程文件夹下自定义一个文件夹(名字随意)接着按照下图所示操作进行HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("D:\\Java\\JavaCode\\ClientDemo-NetBeansPro\\dll\\HCNetSDK.dll", HCNetSDK.class);//文件路径采用绝对路径,可以使用IDEA的Copy Path(下图),自动生成文件路径,如代码中所示Build工程一下,如有异常,按照异常继续讲其他的.dll文件路径导入,接着应该就可以下图画面了第四节点击上图中的注册按钮会提示请先注册,这个功能说简单点就是登陆设备的意思,按照其要求,就是要填写图中除端口外的3个空。如果你的设备已经在萤石云上使用过,证明已经注册了,密码就是你的萤石云的登录密码,用户名是admin(如果没有修改过的话)。如果你不知道设备的IP,使用官方软件SADP进行搜索。如下图所示。其原理是该软件每隔15s发送一个广播包,设备收到后就发送响应包,软件进行解析。最后填写用户名和密码就OK啦。第五节点击注册按钮,会弹出如下图所示的设备。接着点击播放按钮(你们的是预览,我的已经修改),就可以看到画面了,同时云台和设备属性参数设置窗口也会弹出来。第六节 通过浏览器进入设备浏览器就是通过HTTP协议进行访问,如果你没有修改设备的HTTP端口值的话,就在搜索框中键入http://192.168.0.123/(根据自己的设备IP进行修改),然后输入账号和密码进行登陆。没有修改的话,默认是admin/12345,采用chrome浏览器的话,会出现不兼容的情况1,该问题已经解决。通过安装谷歌IE Tab插件,安装好后点击右上角IE Tab图标就会安装 ietabhelper.exe,安装完成后刷新页面就可以让谷歌在IE浏览器的渲染引擎中工作。得到如下图的结果。第七节 基于海康威视网络摄像头SDK的其它种类的二次开发详情见该博客海康威视网络摄像头SDK中Demo的二次开发(运行)。很详细地介绍了各种海康网络摄像头的二次开发。https://info.pcboard.ca/hikvision-google-chrome-compatibility/ ↩︎
不同物理设备之间的数字转换可以说是随处可见,让其智能又强大。驱动设备的引擎是嵌入式软件,它是快速发展的IoT生态系统中不可或缺的一部分。本篇博客主要谈嵌入式软件开发工具。解释什么是嵌入式系统以及需要什么工具能够构建出来一个。你将了解到现在IT市场上最受欢迎的、可用的嵌入式系统软件开发工具。什么是嵌入式软件桌面软件是为计算机编写的,嵌入式软件针对非计算机硬件编写从而控制其功能。硬件包括各种各样的监控设备、传感器、可穿戴设备以及基于所有的现代电器设备。嵌入式技术与网络、信息科技一起构成了IoT系统,并被广泛用于医疗、制造业、工业自动化以及运输、航空(Aviation)等领域。桌面程序和嵌入式程序最核心的区别存在于它们的目的不同。通用的计算机被用于多种意图,这就是它们的软件在众多设备上运行并且可以被重置。相反地,嵌入式软件被用于服务某种它能够运行的设备。除此之外,嵌入式解决方案的开发要考虑环境因素如温度或者湿度,这些会影响设备的运行和性能。嵌入式系统是硬件模块和软件模块的集合。嵌入式系统的硬件至少要包括以下基础的组件:电源SoM(System-on-a-Module)/SoC(System-on-a-Chip)——一个具有微处理器、外围设别、内存以及IO口的板子嵌入式系统的软件至少要包括以下基础的组件:操作系统:Windows CE、Yocto Linux、ThreadX、Nucleus RTOS语言:C、C++、Python、JavaScript等工具:IDE、SDK、PDK、编译工具链、软硬件调试器(ST-Link、Segger)操作系统构成如下图所示。嵌入式软件开发工具种类下面是不同的嵌入式软件设计开发工具及描述。编辑器文本编辑器是你开始创建嵌入式系统的第一个工具,可以用之来写C和C++源码,保存为文本格式。Geany就是一个很好的例子,不仅内存占用少而且轻量级。支持C、Java、PHP、HTML、Python、Perl、Pascal和其他文件类型。基础功能有:语法高亮代码折叠自动补全自动关闭XML和HTML标记代码定位编译器源码使用高级语言写的。编译器就是用来将高级语言代码翻译成低级语言代码——机器能理解的。Keil C51是一个最受欢迎的编译器,用它来创建8051单片机的应用,翻译用C语言写的源码。汇编器这个工具的功能是将人们写的代码转换成机器语言,与直接翻译的编译器相比,汇编器先将源码转换成对象码,最后再到机器语言。GNU Assembler(GAS)被广泛用于Linux操作系统,可以在Macintosh tools package中找到。调试器这是一个重要的测试工具。浏览代码查找bugs和errors,并通知他们出现的位置。调试器可以指出问题出现的行数,因此开发者可以迅速地进行定位。IDA Pro是可以运行在主流操作上的调试器,广受开发者的欢迎。链接器几乎所有的代码都是分片、分模块写的。链接器就是用于将这些分散的代码片连接起来,来创建一个可运行的程序。GNU Id是其中一个链接器。仿真器仿真器是目标系统的替代品,具有相同的功能和组件。该工具用来模拟软件性能,查看代码在实际工作的。开发者可以通过有序得改变参数值来达到立理想的代码性能。一旦所有的代码被检查一遍,就可以嵌入到设备上。IDE工具谈到嵌入式软件开发工具我们不得不说集成开发环境,上边提及的所有工具都需要来创建嵌入式软件。如果分开使用他们会很不方便,增加了项目构建的复杂度。因此,强烈建议使用集成环境。IDE就是对一系列的来发工具进行打包来为开发者提供开发服务。下年列出了市场上一些最受欢迎的IDE软件。PyCharm一个名为JetBrains的捷克国家的公司开发的这个IDE软件。毋庸置疑,PyCharm适合做跨平台的开发,因为它支持在三种主流操作系统上JavaScript、CoffeeScript、TypeScript、Cython、SQL、HTML/CSS、AngularJS、Node.js、模板语言以及其他的编程语言的开发。PyCharm提供高产出的嵌入式软件开发:@ 智能代码补全@ 错误高亮及修复@ 自动代码重构@ 简单的项目切换@ 集成测试@ 虚拟机远程开发@ 支持网页开发框架,像Django、Flask、Google APP Engine、Pyramid、web2pyPyCharm有三种版本供君挑选,社区版、专业版以及教育版,被认为是针对不同编程意图完美的工具。WebStormJetBrains公司另一款IDE,用于CSS、JavaScript、HTML语言的编程。其特点是:@ 自动编译@ 快速代码分析@ 自动代码重构@ 整合版本控制系统@ 集成测试@ 支持多层嵌套:HTML里嵌入JS脚本的同时还可以在嵌入HTML代码,在嵌入的HTML代码中又可以嵌入JS脚本Qt CreatorQt集成的开发环境拥有大量的库、API接口和工具来用C++、JavaScript和QML编程语言为嵌入式设备开发应用程序。特点在于:@ 跨编辑@ 自动编译@ 语法高亮@ 虚拟键盘@ 板上调试@ 功能安全@ 3D/2D用户接口70多个行业领先的嵌入式系统制造商都选择Qt Creator来构建它们的产品,包括汽车、自动化、医疗、电视和机顶盒、物联网、移动应用等等。MPLAB XMPLAB X是美国Microchip Tecnology公司开发的IDE软件MPLAB最新的版本。该软件基于NetBeans开源平台开发,为不同类型的PIC微控制器和数字信号处理器构建应用程序。主要优点:@ 使用简单@ 自动编译@ 标记呈现@ 动态语法检查@ 板上调试@ 仪表盘窗口Visual Studio一个很受欢迎的微软开发平台。不仅可以被用来构建计算机程序和移动应用程序,还可以构建嵌入式软件程序。Visual C++的扩展使得开发者可以在Windows或者微处理器亦或远程Linux机器上调试本地C/C++代码。使用IoT Visual Studio,你可以构建、编辑、调试运行着Linux操作系统的设备。VisualGDB提供了Visual Studio和GNU工具链的接口来构建和调试嵌入式固件。因此你可以通过第三方编译器进而库来配置你的项目。Eclipse最初,Eclipse被用于Java应用程序的开发,现在成为Java编程人员使用最广泛的IDE软件。Eclipse还可以通过插件形式支持其他编程语言,如Ada,ABAP,C,C++,C#,Python,PHP等。Eclipse为嵌入式汽车设备提供了一个分离的包,包含工具和框架,能够简单、快速开发应用程序。NetBeans一款针对Java 8开发的IDE软件,免费且开源。NetBeans被很多社区开发者和用户支持。它还包括PHP和C/C++工具,因此可以使用CSS、JavaScript以及HTML编程语言开发程序。基础特性:@ 小而快的代码编辑@ 简单有效的项目管理@ 快速的UI开发@ 调试@ 多语言支持@ 跨平台@ 插件丰富MATLABMATLAB是一系列工具的集合,它的编程语言被用来数字运算。不同领域的开发者使用MATLAB来创建用户接口,实现算法,以及用其数据块、图表和功能进行工作。其环境可以让用C,C++,C#,Java,Python及其他语言编写的程序与之交互。和MATLAB与生而来的Simulink软件用于做模拟。二者的结合对嵌入式软件开发很有用,因为他们允许设计和编写从原型到生产的嵌入式系统。优点在于:@ 鲁棒且易用的调试工具@ 丰富有效的数学与统计功能@ 坚固的社区@ 优良的工具开发文化Arduino一款开源的IDE软件,为了Arduino微处理器而生,其丰富的特性和库使得嵌入式开发者更简单。优点主要有:@ 带完整组件的开发板@ 带实例代码的库@ 容易上手@ 开源、可扩展的软硬件@ 跨平台@ 社区活跃ARM KeilARM Keil开发工具为基于ARM的设备创建嵌入式应用程序提供了完整的环境。这个软件包涵盖了C/C++编译器、模拟模块、调试器、链接器、汇编器以及中间件库。除此之外,ARM Keil为基于Cortex、ARM处理器的设备提供了模拟板。优点在于:@ 容易上手@ 接口丰富@ 整合第三方库@ 项目示例@ 技术支持@ 适合初学者和专业者很难说你应该选择哪一款工具来进行嵌入式软件开发,因为它们是在是太多了。应该取决于开发者的技能、喜好以及项目需要。在任何情况下,以上所有工具都能帮助开发者加速嵌入式软件开发。总结嵌入式系统和IoT解决方案被应用在广泛领域,提高我们生产力的同时,节约了成本。
NoteExpress是国内主流的学术科研工具,不仅能够帮助学者梳理文献逻辑,而且可以让学者对每一篇记笔记,打标记,导出引用,支持Word插件以及多种个性化特性,满足学者科研的需求。下面就跟笔者一步步探索该软件的使用。文末有福利零,为什么要选择使用文献管理工具当你阅读少量的文件,通过自行建立文件夹是可以达到需要的,但是一旦你的文献阅读量成百上千,你需要建立各种文件夹,而且可能文件夹中的文献有重复,你想快速的定位某一篇你看过的文献很难,除了查找文献记笔记也是很重要的,如果没有文献管理器,你需要手动为每篇文献建立文档来记笔记,工作量繁重。在阅读中,你可能需要对文献日期进行排序,怎么办,查找排序,想想都累。一,数据库建立使用该软件的第一步就是新建数据库,该数据库就是你将来的阵地,所有的操作基本都是在操作这个数据库,本质就是和新建文件夹是一致的。构建一个树层次的文件夹索引,如图所示。数据库包含五个部分,其中最重要的是题录。题录就是文献的各种属性,文献名-作者-机构-类别等。可以显示如下图所示的字段,可谓应有尽有。也可以自定义字段,自行探索。二,重要功能之在线下载选择在线的数据库,国内的比如知网。进行检索,就像在知网官方网站中一样。出现如图所示的检索界面。将勾选的题录进行保存你自定义的文件中。这些文献题录就会成为你的囊中之物,为你服务。点击下载全文。这个需要使用内网进行下载,因为知网服务器会识别登录IP,付费用户才可以。这项服务学校已经为我们购买了。下载完成后,文献题录会出现正方向红色图标,这标志着已经下载完成。接下来就是耐心地进行阅读了。三,重要功能之记笔记读文献最重要的输出就是记笔记,好记性不如烂笔头。读一百遍不如记录一下自己的心得和收获。这样会帮助你更快地了解该文献的对你的意义。选中一条文献题录,会出现如下图所示的工作区域。右侧区域就会出现以文献名称为名的笔记。当然名称可以修改。四,重要功能之Word插件选择NoteExpress中的“选项”->“扩展”,安装Word插件。如图所示是Word里标题栏里会出现NoteExpress的Word插件。在写作中插入选中的引文题录和笔记,就会在文档中自动生成。还有相对应的引用格式,点击下图所示的格式化按钮。就会出现下图,点击浏览按钮会出现样式选择菜单,在搜索框中查找自己需要的引文格式,截至目前,NE引用了4153种参考文献格式。一定要搞清楚开题答辩和论文撰写所需引用的文献格式,这样避免被老师diss。除了此方法,还可以通过在百度学术或者谷歌学术里查找该文献,并进行引用。在百度学术输入要查找的文献,出现下图所示界面。点击引用按钮,会弹出下图三种格式的文献引用内容,直接copy即可。此方法还可以进行批量引用。当然这种方式比较局限,但是适用于大多数要求。五,NE的数据分析功能按照一定检索式收集的文献,其元数据本身隐含了很多该研究方向的信息。例如年份分布展示了研究的热度趋势;关键词分布展示了研究切入点的情况;来源分布展示了哪些刊物更关注这类研究的进展;作者的频次分布展示了该研究领域的牛人;通过计算关键词的共现频次矩阵,可以得到相关系数矩阵,进一步进行聚类分析及可视化展示各要素之间的相关关系,这些都对明晰我们所关注的科学问题提供了帮助。这个功能NE官方支持已经给出了博客。详见这篇博客。六,其他功能自行探索去重功能,自定义显示题录功能参见NoteExpress自定义题录表头显示字段,去NoteExpress官网教学视频看看也是不错的拓展视野方式。下图是官网的所列的教学视频,很丰富,助你在科研路上一路顺风。当在SCI或者IEEE上下载不到我们需要的文献时,可以通过访问SCI-Hub网站进行下载。在学术搜索引擎中查找文献的DOI或者URL进而在SCI-Hub论文下载可用网址链接 - 实时更新上搜索,99%都会有。有些甚至是连学校都没有买版权的文献。:)
1,出现的问题:博主在下图中点击安装按钮给word安装NE插件,在引用文献时出现索引越值、无效类字符串。2,使用的NE版本是word版本是64bit-2010。3,解决方法word插件在系统注册表里没有注册上缘故,在NE安装目录下,找到NTAddinReg.exe文件,双击运行一下。注册表就会出现64位的加载项注册表。这样一来就会很少出现问题。http://www.inoteexpress.com/nesupport/forum.php?mod=viewthread&tid=5146&highlight=NE%2Bword%E6%8F%92%E4%BB%B6 ↩︎
1,SecureCRT官网,破解版下载请点击这里,内含有破解软件;2,下载好压缩包,将其解压后,点击安装软件进行安装,一直点击即可;3,安装好后就可以使用破解软件进行打补丁;4,不需要修改名字和公司直接点击Patch按钮;5,选中你安装路径中的SecureCRT.exe执行文件,会提示成功;6,继续点击Patch按钮选中LicenseHelper.exe执行文件;7,至此破解完毕,开启连接吧 ?。
一,硬件准备:电脑一台网线两条(在AP没有48V输入电源情况下)具有poe功能的交换机(S5110)一条console线用于连接电脑和AP(调试AP)二,实验原理电脑和AP处于相同网段局域网内,二者即可通信。交换机的作用,其一是给AP供电,其二是让电脑和AP处于同一网段内。接着使用TFTP简单文件传输协议给AP进行配置。网络拓扑图是:三,查看AP版本打开交换机,用网线连接交换机和AP,通过console线将AP连到电脑上打开超级终端SecureCRT,点击File->connect,点击回车电脑的终端上出现WA4320-ACN-SI的信息和命令提示符输入display boot-loader,查看AP的版本是否为FAT版本,如果出现xx_fat.bin即为FAT版本,就不要进行胖转瘦了。直接使用web界面就可以操作AP进行配置。如果是xx_fit.bin进行第四步骤。四,上传输入sys,回车,进入系统视图界面这时WA4320-ACN-SI是方括号,显示为[WA4320-ACN-SI]输入interface vlan 1回车,光标显示为[wa4320-aci-si-interface vlan 1],然后输入ip add 192.168.1.2 24回车,即为AP配置了192.168.1.2的地址在电脑上打开命令提示符窗口,ping 192.168.1.2,如果能通,则可以进入下一步,如果不能通,要逐项查找原因,不能通就无法进入下一步将文件夹的tftp32.exe打开5.回到超级终端,确认该AP存储空间是否足够存下将要载入的wa4320s_fat.bin ,使用命令:dir /all(注意中间有空格),如果存储空间不够需使用delete /u wa4320s_fit.bin来删除原有瘦文件 ,如果光标显示为[wa4320-aci-si-interface vlan 1]的,请输入return,直至变成<WA4320-ACN-SI>后,输入tftp 192.168.1.1 get wa4320s_fat.bin,后回车,这时查看tftp界面,如果Bytes下面的数字不停增加,意味着AP正在从tftp的目录中下载fat固件到flash,此为正常,耐心等待下载完成6.回到超级终端SecureCRT,使用命令boot-loader file flash:/wa4320s_fat.bin出现:This command will set the boot file. Continue? [Y/N]输入:Y7.显示成功,如果AP这时重启了,请等待重启完成,进入下一步五,检验断开console线了,将电脑ip更改成192.168.0.12,直接通过网线,使用ie访问192.168.0.50即可进入web管理界面,用户名为admin,密码为h3capadmin
FIFO(先进先出页面置换算法)按照进入内存的先后顺序,进行排序。如果出现相同的页面在内存中,就不做置换。LRU (最近最少使用页面置换算法)按照进入内存的先后顺序,进行排序。后来的页面总是把前面的页面置换掉。OPT(理性页面置换算法)按照进入内存的先后顺序,进行排序。将最长时间才会出现的页面置换掉。实践表明,缺页率大小顺序为:OPT<LRU<FIFO
NE(NoteExpress) 题录按照默认表头格式显示,并不符合每个人对信息的筛选条件。本文提供一种自定义表头的方法。1.NE原显示表头字段如果是学位论文,我想显示字段是“大学”时,怎么办?2.鼠标右键点击题录表头3.此时显示表头信息4.点击自定义选项,出现自定义表头界面在这个界面中,能看到列表表头名称,新建列表表头,可显示的字段,已经显示的列,以及对显示的字段的顺序的调整。5.因为要显示学位论文,所以在字段显示为处选择学位论文,否则是看不到“大学”这个字段的,如图操作后,点击添加即可完成6.添加成功后,表头显示如下图示
网络中不止一台树莓派,默认主机名是raspberrypi,容易和别人的树莓派混淆,所以更改一个独一无二的主机名是很有必要的。树莓派的主机名字存储在/etc/hostname文件中,在/etc/hosts文件中也有映射,所以将这两处文件中的默认树莓派的名字改成你想要的即可。第一步:进入/etc/hostname文件,并更改sudo nano /etc/hostname更改任意你希望的名字,仅限于数字,小写字母 和符号 “-”点击CTRL+O 然后 ENTER 保存点击 CTRL+X 退出第二步:进入/etc/hosts文件,找到127.0.0.1映射的主机名并更改sudo nano /etc/hosts更改任意你希望的名字,同上述名字点击CTRL+O 然后 ENTER 保存点击 CTRL+X 退出第三步:重启树莓派sudo reboot
在工作中遇到一张统计表有多个字段,每个字段都有其筛选条件,写工作汇报需要每个字段的占比来进行分析数据背后的意义。如果按照原来的一次次点击每个字段的筛选条件查询将会耗费大量时间,运用数据透视表能够节约三分之二的时间,而且也不容易出错。1,数据透视表数据透视表是计算、汇总和分析数据的强大工具,可助你了解数据中的对比情况、模式和趋势。请点击:)这是一个教你如何创建数据透视表的官方教程2,举栗子要求:求某届研究生(全校)毕业生参与学术活动情况分布占比(小数点后两位),该字段(研究生毕业生参与学术活动情况)有三个筛选条件:1﹒经常参加 2﹒偶尔参加 3﹒未参加解:Step1: 插入数据透视表,因为所给统计表中没有唯一的标识整体的数据,即全校的,有的数据是各个学院的,所以在第一列前添加索引,如下图所示,索引字全为A,当然你也可以填写任意相同内容,为的是让该字段(索引)具有唯一筛选条件属性;step2:接着,将为整个表插入数据透视表,按照所给链接插入即可;step3:在数据透视表列字段列表中勾选"索引"字段和 “研究生毕业生参与学术活动情况”字段,,结果如下图所示:step4:可以在Excel左侧看到统计数据,然后再在C4单元格中写函数“=B4/1932”来计算百分比,如下图a所示;得出的单元格中的数据格式是小数,不是百分数,需要调整单元格式,如图b所示;最后填充筛选条件的单元格的格式即可,如图c所示a 写函数b 设置单元格格式,选择数字 -> 百分比 -> 小数数位2c 选中单元格“100%”单元格,点击单元格右下角小黑点进行复制单元格3,如果要求某个学院的各个系的某字段的占比,操作和上述一致选取行标签和需要计数的字段按照上述步骤来就好了
平常习惯了用IDE软件IDEA构建Java项目,对java命令行有点陌生,就遇到问题,记录一下!1,java 和 javac 在命令行中测试均成功,执行java文件的编译也成功,但是运行class文件就出现问题,提示找不到类,如下图所示:2,然后就开始排除问题,上述中测试均无问题,证明安装jdk文件没有问题,为什么在java运行class文件会出现问题?查看的配置文件:运行java 和 javac的结果:java命令:javac命令我的jdk\lib文件中没有tool.jar和dt.jar文件,版本1.9,这个问题不影响运行。解决办法:用简单的命令行javac编译后,再用java运行就会出错,这个肯定是出在配置之后的操作,要么是javac命令错误,要么是java命令错误,再搜索了原因,原来是javac 编译带有包名java文件要用java -d . [文件名.class]
痛苦了好多天的问题,以为是自己对框架的不熟悉导致在调用某各类的参数时,出现异常现象。解决的方法从《Thinking in Java 》第四版第2章一切都是对象、第5章初始化与清理中获得,综合了Stack Overflow上的一些观点。在编程的过程中,会经历这样一种情形:在方法的结尾将对象赋值为null和清空集合的操作。其实这对于垃圾回收器来说没有意义。垃圾回收器对于方法内部的变量的回收很容易执行。1,Java中new 出来的对象,也叫对该对象的引用,JVM(Java 虚拟机)垃圾回收机制会根据其寿命决定何时回收该对象。很多时候不需要自己去清除。切记:Java中的对象被不总是被垃圾回收器回收,即对象可能不会被垃圾回收;垃圾回收并不等于“析构”(C++)中;垃圾回收只与内存有关。2,在多线程中,尽量将类的全局变量转换为为局部变量,或者在方法和循环内部定义,再者取决于变量作用域,垃圾回收器更容易决定其是否应该被回收。3,将对象的值赋值为null,相当于把对象的引用清除掉,即把引用对象的指针kill掉,再使用集合就会报空指针异常;调用集合的clear()方法,是把集合内部的对象都清空,而集合的引用还存在。4,将集合作为参数传递到方法中,相当于把集合的引用传递到方法中,在方法中执行任何和集合相关的清除操作,相当于对集合执行清除操作。【上述解决方法解决不了问题,尝试此方法】
问题出现其实这个问题相当简单,自己鼓捣好久,才发现还是自己基本功不扎实,当图片的大小出现在原生的bootstrap类属性限定中,图片会按照自己的大小进行布局,这样就会出现图片小于父div的情况,如下图所示:问题解决找出图片所属类,更改类的属性为block,设置图片的高度为父div的高度,代码如下:#showCarousel .carousel-inner > .item > img { display: block; width:100%; height:父div的高度; }父div包含id=showCarousel的div结果展示如下图所示:图片充满了整个布局,以后遇到这种高度问题,首先想一下要不要将该元素的转换为块级元素。
1,问题出现在做tp5验证码输出时,出现如下图所示的结果2,思考过程页面出现问题,第一推断是自己的html代码出现问题,就打开浏览器的“开发者工具”选项查看代码解释,发现出现了如下图的结果这个错误原因是服务器的问题,请求地址无效,再看解析地址和tp5例子对比没有问题,于是继续搜索原因,期间经历了无数次试探,直到看到了由于php的gd库功能不开启也可以导致图片加载不出来,抱着试一试的态度查看自己的php.ini文件,发现没有开启,开启后重启apache2.4服务,问题终于解决。结果在第4小节的图片中!3,初探gd库PHP 并不仅限于创建 HTML 输出, 它也可以创建和处理包括 GIF,PNG,JPEG,WBMP 以及 XPM 在内的多种格式的图像。更加方便的是,PHP 可以直接将图像数据流输出到浏览器。要想在 PHP 中使用图像处理功能,你需要连带 gd 库一起来编译 PHP。4,成功显示
Windows操作系统下apache2.4配置虚拟主机第一步:在apache2.4的文件夹下找到配置虚拟主机的文件httpd-vhosts.conf,一般是在:Apache24\conf\extra下。在该文件中添加需求的虚拟主机文件目录和域名,以及文件访问权限,代码如下:<VirtualHost *:80> DocumentRoot "H:\文件夹名" ServerName xxx.xxx.com <Directory "H:\文件夹名"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost>PS:需要注意的是,虚拟主机的端口一定要在apache的配置文件中httpd.conf开启监听,比如我的是监听的是80端口,如果是别的端口,就要添加监听端口,代码如下(原来是监听的8888端口,我在写虚拟主机配置文件时写的是80端口,一直出错,后来找资料发现时一定要开启访问端口的监听,即再添加了第二行代码):Listen 8888 Listen 80第二步:配置好虚拟主机文件后,一定要在apache的配置文件中httpd.conf中引用进来,在该文件中添加如下代码:Include conf/extra/httpd-vhosts.confPS:注意虚拟主机配置文件的所在位置,根据实际来写!第三步:修改主机hosts文件,该文件的位置在C:\Windows\System32\drivers\etc,添加如下代码:127.0.0.1 xxx.xxx.comPS:该域名和虚拟主机配置文件中的域名相同!第四步:重启apache服务,在浏览器中输入域名xxx.xxx.com出现所要页面就OK啦!扩充一下知识点:如果监听的是除80端口以外的端口,就需要在域名上写上端口名,形如:xxx.xxx.com:8080在浏览器输入xxx.xxx.com:8080即可访问!
2022年10月