首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

如何快速安全的插入千万条数据

前言 最近有个需求解析一个订单文件,并且说明文件可达到千万条数据,每条数据大概在20个字段左右,每个字段使用逗号分隔,需要尽量在半小时内入库。 思路 1.估算文件大小 因为告诉文件有千万条,同时每条记录大概在20个字段左右,所以可以大致估算一下整个订单文件的大小,方法也很简单使用FileWriter往文件中插入一千万条数据,查看文件大小,经测试大概在1.5G左右; 2.如何批量插入 由上可知文件比较大,一次性读取内存肯定不行,方法是每次从当前订单文件中截取一部分数据,然后进行批量插入,如何批次插入可以使用insert(...)values(...),(...)的方式,经测试这种方式效率还是挺高的; 3.数据的完整性 截取数据的时候需要注意,需要保证数据的完整性,每条记录最后都是一个换行符,需要根据这个标识保证每次截取都是整条数,不要出现半条数据这种情况; 4.数据库是否支持批次数据 因为需要进行批次数据的插入,数据库是否支持大量数据写入,比如这边使用的mysql,可以通过设置max_allowed_packet来保证批次提交的数据量; 5.中途出错的情况 因为是大文件解析,如果中途出现错误,比如数据刚好插入到900w的时候,数据库连接失败,这种情况不可能重新来插一遍,所有需要记录每次插入数据的位置,并且需要保证和批次插入的数据在同一个事务中,这样恢复之后可以从记录的位置开始继续插入。 实现 1.准备数据表 这里需要准备两张表分别是:订单状态位置信息表,订单表; CREATE TABLE `file_analysis` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `file_type` varchar(255) NOT NULL COMMENT '文件类型 01:类型1,02:类型2', `file_name` varchar(255) NOT NULL COMMENT '文件名称', `file_path` varchar(255) NOT NULL COMMENT '文件路径', `status` varchar(255) NOT NULL COMMENT '文件状态 0初始化;1成功;2失败:3处理中', `position` bigint(20) NOT NULL COMMENT '上一次处理完成的位置', `crt_time` datetime NOT NULL COMMENT '创建时间', `upd_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CREATE TABLE `file_order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `file_id` bigint(20) DEFAULT NULL, `field1` varchar(255) DEFAULT NULL, `field2` varchar(255) DEFAULT NULL, `field3` varchar(255) DEFAULT NULL, `field4` varchar(255) DEFAULT NULL, `field5` varchar(255) DEFAULT NULL, `field6` varchar(255) DEFAULT NULL, `field7` varchar(255) DEFAULT NULL, `field8` varchar(255) DEFAULT NULL, `field9` varchar(255) DEFAULT NULL, `field10` varchar(255) DEFAULT NULL, `field11` varchar(255) DEFAULT NULL, `field12` varchar(255) DEFAULT NULL, `field13` varchar(255) DEFAULT NULL, `field14` varchar(255) DEFAULT NULL, `field15` varchar(255) DEFAULT NULL, `field16` varchar(255) DEFAULT NULL, `field17` varchar(255) DEFAULT NULL, `field18` varchar(255) DEFAULT NULL, `crt_time` datetime NOT NULL COMMENT '创建时间', `upd_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10000024 DEFAULT CHARSET=utf8 2.配置数据库包大小 mysql> show VARIABLES like '%max_allowed_packet%'; +--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | max_allowed_packet | 1048576 | | slave_max_allowed_packet | 1073741824 | +--------------------------+------------+ 2 rows in set mysql> set global max_allowed_packet = 1024*1024*10; Query OK, 0 rows affected 通过设置max_allowed_packet,保证数据库能够接收批次插入的数据包大小;不然会出现如下错误: Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (4980577 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable. at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3915) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2598) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2834) 3.准备测试数据 public static void main(String[] args) throws IOException { FileWriter out = new FileWriter(new File("D://xxxxxxx//orders.txt")); for (int i = 0; i < 10000000; i++) { out.write( "vaule1,vaule2,vaule3,vaule4,vaule5,vaule6,vaule7,vaule8,vaule9,vaule10,vaule11,vaule12,vaule13,vaule14,vaule15,vaule16,vaule17,vaule18"); out.write(System.getProperty("line.separator")); } out.close(); } 使用FileWriter遍历往一个文件里插入1000w条数据即可,这个速度还是很快的,不要忘了在每条数据的后面添加换行符(\n\r); 4.截取数据的完整性 除了需要设置每次读取文件的大小,同时还需要设置一个参数,用来每次获取一小部分数据,从这小部分数据中获取换行符(\n\r),如果获取不到一直累加直接获取为止,这个值设置大小大致同每条数据的大小差不多合适,部分实现如下: ByteBuffer byteBuffer = ByteBuffer.allocate(buffSize); // 申请一个缓存区 long endPosition = batchFileSize + startPosition - buffSize;// 子文件结束位置 long startTime, endTime; for (int i = 0; i < count; i++) { startTime = System.currentTimeMillis(); if (i + 1 != count) { int read = inputChannel.read(byteBuffer, endPosition);// 读取数据 readW: while (read != -1) { byteBuffer.flip();// 切换读模式 byte[] array = byteBuffer.array(); for (int j = 0; j < array.length; j++) { byte b = array[j]; if (b == 10 || b == 13) { // 判断\n\r endPosition += j; break readW; } } endPosition += buffSize; byteBuffer.clear(); // 重置缓存块指针 read = inputChannel.read(byteBuffer, endPosition); } } else { endPosition = fileSize; // 最后一个文件直接指向文件末尾 } ...省略,更多可以查看Github完整代码... } 如上代码所示开辟了一个缓冲区,根据每行数据大小来定大概在200字节左右,然后通过遍历查找换行符(\n\r),找到以后将当前的位置加到之前的结束位置上,保证了数据的完整性; 5.批次插入数据 通过insert(...)values(...),(...)的方式批次插入数据,部分代码如下: // 保存订单和解析位置保证在一个事务中 SqlSession session = sqlSessionFactory.openSession(); try { long startTime = System.currentTimeMillis(); FielAnalysisMapper fielAnalysisMapper = session.getMapper(FielAnalysisMapper.class); FileOrderMapper fileOrderMapper = session.getMapper(FileOrderMapper.class); fileOrderMapper.batchInsert(orderList); // 更新上次解析到的位置,同时指定更新时间 fileAnalysis.setPosition(endPosition + 1); fileAnalysis.setStatus("3"); fileAnalysis.setUpdTime(new Date()); fielAnalysisMapper.updateFileAnalysis(fileAnalysis); session.commit(); long endTime = System.currentTimeMillis(); System.out.println("===插入数据花费:" + (endTime - startTime) + "ms==="); } catch (Exception e) { session.rollback(); } finally { session.close(); } ...省略,更多可以查看Github完整代码... 如上代码在一个事务中同时保存批次订单数据和文件解析位置信息,batchInsert通过使用mybatis的<foreach>标签来遍历订单列表,生成values数据; 总结 以上展示了部分代码,完整的代码可以查看Github地址中的batchInsert模块,本地设置每次截取的文件大小为2M,经测试1000w条数据(大小1.5G左右)插入mysql数据库中,大概花费时间在20分钟左右,当然可以通过设置截取的文件大小,花费的时间也会相应的改变。 完整代码 Github

优秀的个人博客,低调大师

如何快速搭建一个短链接服务?

摘要: 很简单的短链接教程。 原文:十分钟实现短链接服务(Node + Express + MongoDB) 作者:MudOnTire Fundebug经授权转载,版权归原作者所有。 短链接我们或多或少都使用过,所谓短链接就是根据较长的原链接url生成一段较短的链接,访问短链接可以跳转到对应的原链接,这样做好处在于:1. url更加美观;2. 便于保存和传播;3. 某些网站内容发布有字数限制,短链接可以节约字数。 短链接实现的原理非常简单,可以概括为: 为每个原链接生成不重复的唯一短链接 将原链接和对应短链接成对保存到数据库 访问短链接时,web服务器将目标重定向到对应的原链接 根据以上思路,我们自己也可以分分钟实现一个短链接生成服务。本文示例使用 node + express + mongodb。 1. 初始化项目 (1). 安装如下依赖: package.json: "dependencies": { "config": "^3.2.2", // 读取项目配置 "express": "^4.17.1", // web服务器 "mongoose": "^5.6.9", // 操作mongodb "shortid": "^2.2.14", // 生成不重复的唯一Id "valid-url": "^1.0.9" // 判断url格式是否正确 } (2). 增加项目配置: 主要用于存放MongoDB的连接字符串和短链接的base url。 config/default.json: { "mongoURI": "mongodb://localhost:27017/url-shorten-service", "baseUrl": "http://localhost:5000" } (3). 增加MongoDB连接方法 config/db.js: const mongoose = require('mongoose'); const config = require('config'); const db = config.get('mongoURI'); const connectDB = async () => { try { await mongoose.connect(db, { useNewUrlParser: true }); console.log(`MongoDB Connected to: ${db}`); } catch (error) { console.error(error.message); process.exit(1); } } module.exports = connectDB; (4). 启动express: index.js: const express = require('express'); const connectDB = require('./config/db'); const app = express(); // 连接MongoDB connectDB(); app.use(express.json({ extended: false })); // 路由,稍后设置 app.use('/', require('./routes/index')); app.use('/api/url', require('./routes/url')); const port = 5000; app.listen(port, () => { console.log(`Server running on port ${port}`); }); 2. 定义数据库模型 我们需要将原链接和对应短链接保存到数据库,简单起见,我们只需要保存一个短链接编码,相应的短链接可以使用base url和编码拼接而成。 models/url.js: const mongoose = require('mongoose'); const urlSchema = new mongoose.Schema({ urlCode: String, longUrl: String }); module.exports = mongoose.model('Url', urlSchema); 3. 生成短链接编码 这是我们实现的关键一步,思路是:用户传入一个长链接,我们首先使用 valid-url 判断传入的url是否合法,不合法则返回错误,如果合法我们在数据库中搜索是否有该长链接的记录,如果有则直接返回该条记录,如果没有则生成一条新记录,并生成对应的短链接。借助于 shortId,我们可以很方便的生成一个不重复的唯一编码。 routes/url.js: const epxress = require("express"); const router = epxress.Router(); const validUrl = require('valid-url'); const shortId = require('shortid'); const config = require('config'); const Url = require('../models/url'); router.post('/shorten', async (req, res, next) => { const { longUrl } = req.body; if (validUrl.isUri(longUrl)) { try { let url = await Url.findOne({ longUrl }); if (url) { res.json({ shortUrl: `${config.get('baseUrl')}/${url.urlCode}` }); } else { const urlCode = shortId.generate(); url = new Url({ longUrl, urlCode }); await url.save(); res.json({ shortUrl: `${config.get('baseUrl')}/${urlCode}` }); } } catch (error) { res.status(500).json('Server error'); } } else { res.status(401).json('Invalid long url'); } }); module.exports = router; 4. 访问短链接跳转到原链接 最后一步非常简单,当用户访问我们生成的短链接时,我们根据url中的短链接编码查询到对应记录,如果存在对应记录我们使用express的res.redirect方法将访问重定向至原链接,如果不存在则返回错误。 routes/index.js const epxress = require("express"); const router = epxress.Router(); const Url = require('../models/url'); router.get('/:code', async (req, res, next) => { try { const urlCode = req.params.code; const url = await Url.findOne({ urlCode }); if (url) { // 重定向至原链接 res.redirect(url.longUrl); } else { res.status(404).json("No url found"); } } catch (error) { res.status(500).json("Server error"); } }); module.exports = router; 测试一下: 访问短链接: 这样,一个简单的短链接生成服务就完成了,往往在我们看来很神奇的技术其实背后的原理和实现很简单,希望本文对大家有所启发。 最后,推荐大家使用Fundebug,一款很好用的BUG监控工具~ 本文Demo地址:https://github.com/MudOnTire/url-shortener-service 关于Fundebug Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!

优秀的个人博客,低调大师

快速降低成本建立自己的网站

网站是什么? 网站的定义 网站是什么?可能大部分人头脑中出现的第一映像就是淘宝啊、京东啊、网易,但若要问对于网站的定义,很多人却答不出来,百度百科是这样定义网站的: 网站(Website)是指在因特网上根据一定的规则,使用HTML(标准通用标记语言下的一个应用)等工具制作的用于展示特定内容相关网页的集合。简单地说,网站是一种沟通工具,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。人们可以通过网页浏览器来访问网站,获取自己需要的资讯或者享受网络服务。 网站现状 目前国内网站数量接近400万个,有个人的,也有企业的,还有政府机关单位的,作为我们个人,有时候也想拥有一个属于自己的网站,并不是所有的人建立网站都是为了赚钱盈利,可能一部份人只是想把自己的一些东西通过互联网推送出去,分享给更多的人看到。 网站的用途是什么? 从企业的角度来看 1 可降低广告宣传费用,让客户快捷地找到企业资料2 随时可获取和发布商业信息,寻找潜在客户,促成贸易。3 可提供每天24小时的产品宣传服务。4 利用互联网扩大自己的知名度。5 在网上出售商品,降低销售费用。6 更快捷地了解客户需求。7 有利于开拓国际市场。8 更好地与供应商、销售渠道和合作伙伴沟通与交流。9 改善组织结构和管理体系,提高工作效率,及时适应市场变化。10 可以树立现代化形象 从个人的角度来看 1 完全依据兴趣,享受建站的乐趣,对建站充满好奇心。2 学习建站技能和建站技术。3 信息交流和信息分享。通过互联网可以让更多人知道你。4 学习网站seo优化,建了网站,才能进行seo优化实践。5 建站赚钱,根据想法或者有价值的产品或者广告进行变现。 如何零基础拥有自己的网站? 那大多数人都是不具备制作网站技能的,当然,有人使用的方法是直接花钱请人为自己做一个网站并且帮助日常维护,这个方法虽然可行,但是似乎失去了自己创建网站的乐趣。那接下来小编就来教大家另外一种创建个人网站的方法。 网站必要资源:域名+云主机(云服务器或者虚拟主机)+建站程序 第一步:我们得想好我们要做一个什么类型的网站及我们做网站的目的是什么。确定类型的时候尽量垂直某一个领域。比如你要做技术博客类,信息资讯类的。 第二步:购买域名,确实好了网站的方向后,我们得先去购买一个域名,购买域名的平台很多,在这里就推荐一个大的平台吧,就是阿里云,购买域名的时候记住,一定要购买.com的域名,因为.com的域名是国际域名,适用性非常强。注册域名时域名尽量和网站主题相关,虽然好一点的域名都被别人抢注完了,但我们只是做个人小网站,所以不必太过于在乎域名。 第三步:选定云主机(云服务器)。这里也是推荐使用阿里云的云主机,稳定和安全。如果你是学生身份,可以选阿里云学生款 不是学生的选择这款阿里云全民上云 。 第四步:网站备案。如果在第三步选择了香港地域或者国外地域的云服务器,那么这一步就可以免备案。选择国内地域的云服务器一定要备案!!个人备案是不收费的。备案时间大概需要半个月。 第五步:搭建网站程序。如果你没有技术,可以选择阿里云自营建站一套龙建站服务。有web开发技术的话,可以自行搭建web程序。这一块小编后续会撰写相关的文章。 第六步:域名地址解析绑定阿里云如何正确解析域名完整步骤(图文操作) 首先购买好了服务器,会有一个公网IP地址,然后在把你的公网IP地址与你购买的域名绑定一下,就可以用域名访问的网站了。 第七步:网站搭建成功如果你要做其它领域的网站,可以找其它网站模板建站,阿里云平台提供了大量的网站模板---阿里云网站模板,有兴趣的可以去在线浏览下,大家有兴趣可以参考下。如果你有web技术,完全可以自己开发网站包括模板。 总结:上面所有步骤中,最麻烦的属于搭建网站程序。如果你不差钱,可以直接购买阿里云官方的网站模板产品,只要会打字就行,一年也就四五百元钱,包含了云主机的价格。如果你想自己学技术来搭建网站程序,那就要好好花点时间了。在这里我推荐用wordPress建站程序。可以省掉很多精力和学习成本。熟练的话,一上午就能建一个网站(不包括网站优化) 【提示】这里着重推荐建站程序WordPress,原因很简单:功能强大,主题和插件多,易于扩展,你用别的建站程序,主题和插件如果不能友好的扩展,后面你的网站会不好加新功能。 如何找免费的网站模板? 这里以wordpress为例。推荐几个免费的WordPress模板地址。当然网上很多WordPress免费模板的网站。还有就是如果你需要一些功能强大的网站主题模板,一般需要收费。免费的模板,一般功能不多。 快来多多支持小编吧!优惠多多哦

优秀的个人博客,低调大师

# iOS 使用 InjectionIII 注入动态库实现快速调试

前言 最近在看 "戴老师" 专栏推出的 "App 如何通过注入动态库的方式实现极速编译调试?" 感触很深, 相信每个 iOS 的小伙伴在写代码的时候, 都存在这个烦恼, 每次修改个小功能, 都需要重新 Build 一次, 才能运行, 当项目功能不断积累到一定程度时, 编译时间可能超乎我们想象, 每次修改个 Color, text 等等, 都要经历一次漫长的等待。 真羡慕写 前端 Flutter 的同事呀, code 一修改好, 不到 1S 就能很快的看到修改结果.原来在 iOS 上早就有大佬推出了 注入动态库的方式来解决由于 OC 采用 "编译器" VS "链接器" 特性进行编译链接导致的 调试周期过长的问题。 使用 InjectionIII 解决项目编译时间过长 使用 InjectionIII 可以加快调试的速度, 并且可以保证程序不需要重启, 即可达到源码修改后的效果。 并且其代码是完全开源的 InjectionIII。 其实现原理大家可以直接跳转到 "戴老师" 专栏去查看 App 如何通过注入动态库的方式实现极速编译调试? 讲的非常详细. 安装方式 方式一: 直接通过 github clone 项目下来, 运行。 如果遇到签名报错, 可直接到 Build Setting 将 Code Signing Identity 将签名取消掉。 方式二: 直接到 App Store 搜索 InjectionIII 下载 运行即可。 运行之后点击应用图标选择 Open Project, 并且选择我们要注入动态库的应用. 然后在我们注入的项目中 "AppDelegate" 的 - (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 添加代码 #if DEBUG // iOS [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load]; #endif XCode10 是这个 #if DEBUG // iOS [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle"] load]; #endif 最后到我们需要监听的页面里面重写这个方法即可 OC: - (void)injected { [self viewDidLoad]; [self viewWillAppear:YES]; [self viewWillDisappear:YES]; } Swift extension UIViewController { @objc func injected() { viewDidLoad() viewWillAppear(true) viewDidAppear(true) } } 参考 App 如何通过注入动态库的方式实现极速编译调试?InjectionIII 最后 希望此篇文章对您有所帮助,如有不对的地方,希望大家能留言指出纠正。谢谢!!!!!学习的路上,与君共勉!!! 本文原创作者:Jersey. 欢迎转载,请注明出处和本文链接

优秀的个人博客,低调大师

开源APM监控Pinpoint的快速部署和使用

版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问我的博客 https://blog.csdn.net/smooth00 Pinpoint是用于大规模分布式系统的APM工具。它是在Dapper(一个由Google构建的分布式系统跟踪基础架构)之后构建的,为开发人员提供有关复杂分布式系统行为的更多信息。 开源地址:https://github.com/naver/pinpoint Pinpoint作为一款非常优秀的开源APM监控平台,和其他开源系统一样,最繁琐的应该是部署,但是如果你能通过Docker的方式进行部署,我们就可以感受到一键部署的便捷: Docker镜像地址:https://hub.docker.com/u/pinpointdocker Docker-compose地址:https://github.com/naver/pinpoint-docker 一、部署前准备 在Centos7系统上安装Docker和docker-compose yum update -y yum install docker epel-release python-pip -y pip install --upgrade pip pip install docker-compose 对于docker-compose也可以安装指定版本(比如最新版的,因为不同版本支持不同格式的docker-compose文件) yum update -y nss curl libcurl sudo curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose 为了加速docker镜像pull速度,可以修改daemon.json # cat /etc/docker/daemon.json {"registry-mirrors": ["http://579fe187.m.daocloud.io","https://pee6w651.mirror.aliyuncs.com"]} 启动docker systemctl enable docker systemctl start docker 二、安装Pinpoint 按照官网的docker部署方式:https://github.com/naver/pinpoint-docker(部署前把宿主机防火墙都关了) git clone https://github.com/naver/pinpoint-docker.git cd Pinpoint-Docker docker-compose pull && docker-compose up -d 直接这样部署可能会有问题,比如我们只在一台宿主机上部署,我们可以用git命令下载,或是用curl命令先下载zip再解压: sudo curl -L https://github.com/naver/pinpoint-docker/archive/master.zip -o /opt/pinpoint-docker.zip cd /opt upzip pinpoint-docker.zip -d . cd /opt/pinpoint-docker-master 编辑docker-compose.yml,将多个节点的zookeeper改成一个节点(注释掉不需要的): #zookeepers zoo1: image: zookeeper:3.4 restart: always #hostname: zoo1 hostname: 172.17.2.84 environment: ZOO_MY_ID: 1 #ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 ZOO_SERVERS: server.1=0.0.0.0:2888:3888 networks: - pinpoint #zoo2: # image: zookeeper:3.4 # restart: always # hostname: zoo2 # environment: # ZOO_MY_ID: 2 # ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888 # networks: # - pinpoint #zoo3: # image: zookeeper:3.4 # restart: always # hostname: zoo3 # environment: # ZOO_MY_ID: 3 # ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888 # networks: # - pinpoint 如还有问题,请修改相对路径为绝对路径 ... volumes: - /home/pinpoint/hbase - /home/pinpoint/zookeeper ... 基本我在根目录下,运行docker-compose up -d 就能完成docker集群的部署(在后台进行),如果是想看清部署的整个过程,直接用命令: docker-compose up 启动完后容器: ​ 用Rancher查看能比较直观: ​ 安装完后,就可以连接http://172.17.2.84:8079查看,除了一个quickapp应用,什么也没有: ​ 三、部署监控代理 为了监控我们的应用(tomcat、Java、weblogic等),就需要部署监控代理,这个非常简单,首先是去官网下载同版本的agent包:https://github.com/naver/pinpoint/releases/download/1.8.0/pinpoint-agent-1.8.0.tar.gz 将agent包解压到应用(以tomcat为例)目录下: tar zxvf pinpoint-agent-1.8.0.tar.gz -C pinpoint-agent 修改配置文件pinpoint.config,将collector的ip配置为监控收集服务pinpoint-collector的IP: ​ 然后修改tomcat的启动文件catalina.sh,添加javaagent配置参数(这一点和其他商用APM监控工具一样): JAVA_OPTS="$JAVA_OPTS -javaagent:/usr/apache-tomcat-7.0.54/pinpoint-agent/pinpoint-bootstrap-1.8.0.jar" JAVA_OPTS="$JAVA_OPTS -Dpinpoint.agentId=APM-104" JAVA_OPTS="$JAVA_OPTS -Dpinpoint.applicationName=tomcat7-test" 除了javaagent参数,还有agentId参数(应用的唯一标识,不允许和其他应用重名),和applicationName(应用名)。 配完后,就可以重启tomcat了,那么在界面上就能看到新追加的应用了: ​ 对于微服务的jar包也能进行监控: java -javaagent:/mypath/pinpoint-agent/pinpoint-bootstrap-1.8.0.jar -Dpinpoint.agentId=APM-104 -Dpinpoint.applicationName=tomcat7-test -jar myapp.jar 四、使用手册 1. 查看调用关系 1.1 访问地址 http://yoururl 1.2 选择应用 ​ 默认两层展示 ​ 调整层级深度: 示例为前端调用4层追溯,后端调用4层追溯(4层为最深层级) ​ 结果展示: ​ 在图片内按鼠标滚轮调整图片大小。 连线上数字为调用次数 ​ 选择更多时间范围(默认最新5分钟) ​ 2.查看调用链 鼠标按住右键,选中图中区域,松开右键,则展示选中时间段调用层级 ​ 展示结果: ​ 默认按耗时排序 选中某一调用,展示详细调用链及耗时 ​ 选中timelinetab可查看耗时情况: ​ 3. 查看错误信息 3.1 选择错误应用 机器应用抛出错误,机器应用会标红 ​ 3.2 查看详细信息 选中应用,去除成功多选按钮选中对勾,按住鼠标右键,选中红点范围,松开鼠标右键,即可查看详细错误信息: ​ 结果为: ​ 选中某次错误请求,可在详细列表内找到详细错误信息 4. 查看应用情况 选中某一应用 单击inspector ​ 选中某一机器id,时间段,可展示jvm详细信息 ​ 其中内容包含:Jvm内存使用情况,Jvm永久带使用占用空间,Cpu使用情况,每秒处理的消息数(S标识操作系统,U标识此应用),Jvm线程情况,单请求平均响应时间等。

优秀的个人博客,低调大师

使用docker快速搭建Permeate渗透测试系统实践

一、背景 笔者最近在做一场Web安全培训,其中需要搭建一套安全测试环境;在挑选渗透测试系统的时候发现permeate渗透测试系统比较满足需求,便选择了此系统;为了简化这个步骤,笔者将系统直接封装到了docker当中,同时编写了一套启动文档,希望到时候给学员和读者参考。 二、操作实践 数据库搭建 permeate搭建 安装配置 三、数据库搭建 permeate渗透测试系统使用的数据库是MySQL,因此笔者需要先安装mysql数据库服务,为了简化安装,便直接使用了docker方式进行,参考命令如下 docker run --name mysqlserver -e MYSQL_ROOT_PASSWORD=123 -d -i -p 3309:3306 mysql:5.6 启动之后,可以使用宿主机的MySQL管理软件连接测试,如下图所示 四、permeate搭建 在安装完MySQL服务之后,便可以安装permeate系统了,笔者已经将所需PHP和nginx环境封装好了,因此只需下载镜像运行即可 4.1 运行容器 在运行容器时候需要考虑两个问题,首先需要将web端口映射出来宿主机才可以访问,第二个是需要考虑此容器要能访问得到mysql服务,因此参考命令如下: docker run --name permeate_test --link mysqlserver:db -d -i -p 8888:80 registry.cn-hangzhou.aliyuncs.com/daxia/websafe:init 4.2 启动服务 在启动容器之后,通过浏览器访问http://localhost:8888/并不能打开网页,原因是因为nginx服务和PHP服务都还未启动,启动的命令参考如下所示: docker exec permeate_test zsh -c "nginx && /usr/sbin/php-fpm7.2 -R" 此时再通过浏览器访问http://localhost:8888/,便可以打开安装协议页面,如下图所示 五、安装配置 安装过程比较简单,但在填写数据库地址的时候需要注意,我们已经将mysqlserver链接到了permeate容器当中,此时数据库地址直接填写db即可,数据库密码笔者在启动MySQL容器时设置的为123,这里也填写123,参考如下图所示 再次点击下一步的时候,能看到页面当中返回数据表安装成功的提示,如下图所示 点击进入首页按钮之后,便可以来到首页,首页如下图所示 六、图书推荐 如果对笔者的文章较为感兴趣,可以关注笔者新书《PHP Web安全开发实战》,现已在各大平台上架销售,封面如下图所示 作者:汤青松 日期:2018-11-26 微信:songboy8888

优秀的个人博客,低调大师

使用Docker快速部署ELK分析Nginx日志实践

一、背景 笔者所在项目组的项目由多个子项目所组成,每一个子项目都存在一定的日志,有时候想排查一些问题,需要到各个地方去查看,极为不方便,此前听说有ELK这种神器,搜索了一下,发现利用docker搭建似乎并不麻烦,于是进行了一番尝试,结果还比较顺利,将此过程完整记录下来,希望留给有需要的读者进行参考。 笔者这次实践的过程当中参考了较多的文档与笔记,参考的链接地址有:Docker ElK安装部署使用教程 、Docker Hub官网、Docker ELK使用文档 二、操作概要 服务安装与运行 数据导入与校验 绘图配置与展示 三、服务安装与运行 安装ELK有很多种方式,比如源码、rpm包,或docker;不过docker又分为了单个安装与ELK打包安装,笔者这里是通过docker打包安装,因为这样的方式相比来说最为简单,因为只需要下载镜像,然后运行起来就可以了 3.1 镜像下载 ELK镜像已经被docker官方收录,因此只需要简单的命令即可拉取到镜像;但考虑到ELK镜像比较大,在拉取过程当中存在比较慢的情况,因此笔者使用了阿里云的加速器来提速;笔者使用的是MAC版本的docker,参考配置方法如下: 3.1.1 镜像加速 右键点击桌面顶栏的 docker 图标,选择 Preferences ,在 Daemon 标签下的 Registry mirrors 列表中将 https://k0pf39f8.mirror.aliyuncs.com加到registry-mirrors的数组里,点击 Apply & Restart按钮,等待Docker重启并应用配置的镜像加速器,如下截图 3.1.2 镜像获取 设置好加速地址之后,笔者就可以开始拉取ELK镜像,参考命令如下: docker pull sebp/elk 笔者当前镜像laster对应的版本为6.2.4,如果读者以后看到此文章,在搭建的时候遇到一些问题,可以在命令后面加上:6.2.4来指定该版本,减少意外产生; 下载镜像之后可以使用docker的命令来验证是否成功,参考命令如下: docker images 笔者执行后docker返回结果如下 REPOSITORY TAG IMAGE ID CREATED SIZE sebp/elk latest c916150705cc 2 weeks ago 1.49GB 在结果当中可以看出,ELK镜像已经下载下来,占用了将近1.5GB空间 3.2 容器运行 运行此容器的时候,需要将宿主机的端口转发到该容器,其中ES端口为9200,kibana端口为5601,logbate端口为5044;另外笔者建议将配置文件和数据存放在宿主机,便于后期维护,因此还需要将宿主机目录挂载到容器/data当中;最后构造的命令如下: docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -v /Users/song/dockerFile:/data -it -d --name elk sebp/elk 笔者在运行容器的参数当中加入了后台运行-d参数,这样笔者就不怕误操作突然把容器停止了,但放置于后台运行,ELK的服务器启动过程是不可见的,这个启动时间根据你机器的性能所决定,笔者电脑大约在10秒钟左右;如果觉得启动失败,也可以将该容器删除,然后重新创建一个容器,上述命令中的-d删除即可看到启动过程。 3.3 数据导入与校验 容器运行之后,笔者需要验证是否启动成功,可以通过浏览器访问kibana和ES的页面是否成功来判断。 3.3.1 检查Kibana 通过浏览器访问kibana,如果正常出现界面,则代表启动成功,URL地址如下: http://localhost:5601/ 当浏览器访问成功之后,参考如下图所示: 3.3.2 ES服务检查 验证kibana启动成功之后,接着继续验证ES服务是否启动成功,URL地址如下 http://localhost:9200/_search?pretty 访问之后,此时ES里面应该是没有数据的,出现的界面如下 四、配置与验证 在保证es和kibana服务启动完成之后,笔者还需要进行一些数据导入步骤 4.1 logstash配置 logstash配置主要有三个地方要处理,首先是输入源在什么位置,然后是对数据进行过滤或者格式化,最后是需要将数据输出到什么地方;笔者在下方的配置只做了其中两项,因为在nginx日志当中已经将日志格式化了,编辑配置文件命令参考如下: vim /Users/song/dockerFile/config/logstash.yml 配置文件内容参考如下 input { file { path => "/data/logs/access.log" codec => "json" } } output { elasticsearch { hosts => ["127.0.0.1:9200"] } stdout { codec => rubydebug } } 在配置文件当中,可以看到日志文件存放的位置在 "/data/logs/access.log"当中,输出的地址是127.0.0.1:9200,这是本机的ES服务 4.2 nginx日志格式 因为笔者对logstash的配置文件语法不太熟悉,在里面写过滤器和筛选项比较费时间,所以选择直接更改nginx中的日志格式,将nginx的日志文件设置为json格式,在更改nginx配置文件之前,需要获取nginx配置文件路径,参考如下命令 sudo nginx -t 返回结果 Password: nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful 在返回的结果当中已经可以看到配置文件所在的位置,使用vim编辑配置文件,参考命令 vim /usr/local/etc/nginx/nginx.conf 在http级别下增加自定义日志格式,和日志路径,参考配置如下: log_format json '{"@timestamp":"$time_iso8601", "@version":"1","host":"$server_addr", "client":"$remote_addr", "size":"$body_bytes_sent", "responsetime":"$request_time", "domain":"$host","url":"$uri","status":"$status"}'; access_log /data/logs/access.log json; 笔者配置截图如下所示 4.3 启动logstash 前面已经将日志格式与logstash配置好,现在笔者需要启动logstash开始收集日志,启动logstash之前需要先进入容器里面,进入容器参考命令如下: docker exec -it elk bash 进入容器之后,笔者需要启动logstash来收集数据,启动的时候需要带两个参数进去,第一个是logstash的数据暂存位置,第二个是使用的配置文件,因此构造的命令如下所示: /opt/logstash/bin/logstash --path.data /tmp/logstash/data -f /data/config/logstash.conf 4.4 添加数据 现在只要nginx产生日志,logstash就会实时将日志发送到ES服务当中,在发送数据时,终端窗口也会发生变化,如下图所示 五、 绘图配置与展示 当数据导入之后,笔者才可以使用kibana的图形化来查看数据了,所以首先确认一下ES中是否有数据,确认有数据后就可以进行绘图配置,配置完成之后就可以进行筛选日志等操作了。 5.1 ES数据检查 当数据添加到ES服务器当中后,笔者可以通过ES服务提供的URL来查看其中的数据,URL地址如下所示: http://localhost:9200/_search?pretty 就会看到笔者刚刚输入的日志内容,如下图所示 当看到total数量变大,并在下面的数据项中看到了nginx日志信息时,则代表笔者导入数据成功了。 5.2 kibana索引配置 通过浏览器访问kibana,URL地址如下 http://127.0.0.1:5601/app/kibana#/management/kibana/index?_g=() 点击左侧导航栏的Discover链接,便可进入创建索引模式界面,如下图所示 点击页面右下方的next按钮,会跳转到下一个页面,在此页面还需要选择一个时间维度,如下图所示 在此点击下一步,便创建kibana的索引完成,此时再次点击左侧导航栏的Discover链接,便可以看到刚才创建索引的一些视图,如下图所示 在图中有一个input输入框,笔者可以在里面填写筛选所需要的关键词;如果没有筛选出结果,也可检查左侧的时间筛选项是否设置正确,如笔者的时间筛选项设置的是Today,也就代表筛选当天的数据。 ELK的整体操作流程比较简单,首先是logstash收集各种日志并进行过滤,然后将过滤后的内容发送到ES服务中,最后用户通过Kibana的页面查看ES中的日志数据; 作者:汤青松 微信:songboy8888 日期:2018-08-25

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册