SegmentFault Fundebug最新的文章
2022-07-01T09:08:44+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
Fundebug JavaScript插件支持监控HTTP请求数据
https://segmentfault.com/a/1190000042055989
2022-07-01T09:08:44+08:00
2022-07-01T09:08:44+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><img src="/img/remote/1460000019373421" alt="" title=""></p><h3>Fundebug 前端异常监控服务</h3><p><a href="https://link.segmentfault.com/?enc=eCdX%2Fs11in7aMTFH0YcxEQ%3D%3D.BOV6ZhhkElwnD6%2BZbMFY9Z%2BPDskeBpESysPWZm6Z3bY%3D" rel="nofollow">Fundebug</a>提供专业的前端异常监控服务,我们的插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括但不限于 JavaScript 执行错误以及 HTTP 请求错误。</p><p>并且,Fundebug 支持 Source Map 还原,记录用户行为以及“录制”用户操作视频,帮助开发者快速复现 BUG,提高 Debug 效率,欢迎大家免费试用~</p><p>Fundebug 前端异常监控插件更新至 2.8.4,支持配置 <code>monitorHttpBody</code> 和 <code>monitorHttpResponse</code>。</p><p>在每一个错误事件的详情页,有一个“用户行为”的标签。用户行为记录了用户点击、用户输入、网络请求、页面跳转、控制台日志等行为数据。</p><p><img src="/img/remote/1460000022282667" alt="" title=""></p><p>目前网络请求用户行为中不会记录请求的Body的请求的返回数据,为了更好地Debug,特新增3个可配置属性。<br>默认为<code>false</code>,需要设为<code>true</code>才会开启。</p><h3>1、新增 monitorHttpBody 属性</h3><pre><code class="js">fundebug.init({
monitorHttpBody: true
});</code></pre><h3>2、新增 monitorResponse 属性</h3><pre><code class="js">fundebug.init({
monitorHttpResponse: true
});</code></pre><h3>3. 新增 sensitives 属性</h3><p>因为body中可能包含敏感信息,比如手机号、密码、银行账号等。默认会对<code>password</code>字段过滤。<br>为了更灵活地过滤敏感信息,可配置<code>sensitives</code>属性。</p><pre><code class="js">fundebug.init({
sensitives: ['bankaccount', 'email', 'phoneNumber']
});</code></pre><h3>参考</h3><ul><li><a href="https://link.segmentfault.com/?enc=sRc%2F5BqAbma9qdah8vemHw%3D%3D.EpDv7idDq27jUySQaz32uxZBa8bqImpwBMO9DWeHF1d05UL8fQWILVR2CXq8JHogv5Tmu%2BK4iAIyvaY%2BBcLMw2VaZFCyeoi%2BG0wNqDZwWk8%3D" rel="nofollow">配置 monitorHttpBody 属性</a></li><li><a href="https://link.segmentfault.com/?enc=Ui9dlH%2FCbyhxypoUUySntQ%3D%3D.WX2PPyrS3qMATgGiZ8YR0NlG835QgMX%2FivkZ7nhNzod63NddU1XrRgElBBHuyR6BGvwMFzK%2BCaEHWszpRZYiw2PgF6MmtaQmmTuggEtAsmg%3D" rel="nofollow">配置 sensitives 属性</a></li><li><a href="https://link.segmentfault.com/?enc=YsdT5QzlSh2wphvP3lXYmA%3D%3D.klkFTaHkEaACoCUrTDVbyT9SBfVO7OpW6EltFb3OxhJnXWSogeQMmfUeI6KijAyo3PJkMSk3bZE76iNY1bKDvxH89Du97ey0ryOezc%2FyYbV%2BNYvET7xUI2OEg1no9hqQ" rel="nofollow">配置 monitorHttpResponse 属性</a></li></ul>
Fundebug前端异常监控插件更新至2.4.0,支持配置breadcrumbSize
https://segmentfault.com/a/1190000022282664
2020-04-07T09:08:04+08:00
2020-04-07T09:08:04+08:00
Fundebug
https://segmentfault.com/u/fundebug
2
<p><strong>摘要:</strong> 灵活配置 breadcrumbSize,记录更多用户行为数据。</p>
<p><img src="/img/remote/1460000019373421" alt="" title=""></p>
<h3>Fundebug 前端异常监控服务</h3>
<p><a href="https://link.segmentfault.com/?enc=f2PENsyDNcafxIb0Xayv6w%3D%3D.Sr3hILH7X6r2Oufbdr4ejLZVQVN8mZQgbn8hL9ZL9FA%3D" rel="nofollow">Fundebug</a>提供专业的前端异常监控服务,我们的插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括但不限于 JavaScript 执行错误以及 HTTP 请求错误。</p>
<p>并且,Fundebug 支持 Source Map 还原,记录用户行为以及“录制”用户操作视频,帮助开发者快速复现 BUG,提高 Debug 效率,欢迎大家免费试用~</p>
<p>Fundebug 前端异常监控插件更新至 2.4.0,支持配置 breadcrumbSize 和新增 leaveBreadcrumb()接口。</p>
<h3>1、新增 breadcrumbSize 属性</h3>
<p>在每一个错误事件的详情页,有一个“用户行为”的标签。用户行为记录了用户点击、用户输入、网络请求、页面跳转、控制台日志等行为数据。</p>
<p><img src="/img/remote/1460000022282667" alt="" title=""></p>
<p><code>breadcrumb</code>指用户行为列表中的行为记录,用户行为数据的长度默认为 20 条。如果项目相对复杂,需要记录的数据量会更多,那么用户可以设置 breadcrumbSize 属性,来配置合理的长度。</p>
<pre><code class="js">fundebug.init({
breadcrumbSize: 30,
});</code></pre>
<p>在 HTML 中配置<code><script></code>标签中配置 apikey 属性</p>
<pre><code class="html"><script
src="https://js.fundebug.cn/fundebug.2.4.0.min.js"
breadcrumbSize="30"
></script></code></pre>
<h3>2、新增 fundebug.leaveBreadcrumb()方法</h3>
<p>为了方便更好地复现 bug,有时候需要更详尽的用户行为数据,我们可以在某些关键节点使用<code>leaveBreadcrumb()</code>进行手动埋点,获取的数据会加入到用户行为列表中。</p>
<pre><code class="js">fundebug.leaveBreadcrumb({
message: "调用fetchData()接口",
page: "商品详情页面",
});</code></pre>
<p>捕获的异常的用户行为记录中会包含我们手动埋点的信息。</p>
<p><img src="/img/remote/1460000022282668" alt="" title=""></p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=q%2BO0JhVcZD5OhwfrejwQ3w%3D%3D.z1ZKStrqwGn7mQT7LP58VonQxM94wkvgdQosoG%2FY7QZMJyWj1UWD9%2Fk9KNA2XsOqtkhKJQJ40RKkqLCJJGqw0xKa67WgTVA8aSRYMW3lmZk%3D" rel="nofollow">配置 breadcrumbSize 属性</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2Bd4K9nnXn2SPPA4gFPm2RQ%3D%3D.KXJMDvT150scw%2FKXzAt4sqru62OGzcpuqI5uh7pEIeHqNTWzzB6qo8M%2F8Tel8Hi5r%2BeTYOgIRIUE545JXgvAQVOpGlnk%2FSiWsqIOXjgnbI4%3D" rel="nofollow">fundebug.leaveBreadcrumb()接口</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=VeQd9ywTJlA53XoZ3LQoiQ%3D%3D.kLyI1p1KVgDS6Hr9euMObQsBznffS8ch3l7yLjzkseI%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了40亿+错误事件,付费客户有阳光保险、达令家、核桃编程、荔枝FM、微脉等众多品牌企业。</p>
Fundebug支持配置实时报警
https://segmentfault.com/a/1190000022138960
2020-03-25T11:25:17+08:00
2020-03-25T11:25:17+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 将报警间隔设置为实时,第一时间接收提醒!</p>
<p>为了防止报警过于频繁,在项目设置的“报警规则”页面,我们对报警间隔做了限制,默认一个项目 30 分钟内最多报警一次。当然,时间可以调节,最少能调整到 15 分钟。然而在实际使用中,客户希望每一个错误都能够收到实时的报警。经过慎重考虑,我们决定放开限制,做到支持实时报警。</p>
<p><img src="/img/remote/1460000022138963" alt="" title=""></p>
<p>如果您配置了“实时”,我们建议:</p>
<ul>
<li>接入第三方报警(企业微信、钉钉等),做到真正意义上的实时;我们对邮件报警数量做了限制,每天累计超过 96 封则不再发送;第三方报警没有此限制;</li>
<li>合理配置报警规则,防止报警过度;如果发现报警消息过于频繁,请及时调整报警规则;</li>
</ul>
<p>另外,如果您的数据量很大,请谨慎选择实时报警,因为每一个错误都会发送一次报警提醒。假设一天新增 1 万个错误,那么将会收到 1 万条报警消息。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=jgqBlEcZ1q5ph98UKHLcVg%3D%3D.9%2B6XkGkN76HcEmZc4%2F5%2BPxq4PhZLy%2BN6K3ZSGu0KSCIwo5mAVsoApouU97F3EYmb" rel="nofollow">Fundebug 配置报警规则</a></li>
<li><a href="https://link.segmentfault.com/?enc=QOate8WhmEM9Jg1KiIiNaQ%3D%3D.l3wSHMDoU3WeEaGZbShJ1LOBNZhdK2mGfqoYxhh1E%2B4ItUVxy6qtL%2F%2FQIFhfa6JT" rel="nofollow">Fundebug 接入第三方报警</a></li>
</ul>
使用Fundebug API 批量上传Source Map
https://segmentfault.com/a/1190000021887767
2020-03-02T10:51:09+08:00
2020-03-02T10:51:09+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 通过代码批量上传 Source Map,实现流程自动化!</p>
<p><a href="https://link.segmentfault.com/?enc=P7SSvDtyHxrrPGrH5PXdDw%3D%3D.irHc7ps%2Fd1PaZ85gV44WEzgNop3%2F9RpTj7B6oOfkngSatgw3ymku7ztb%2FtwtSz8jbt7F6d3HGUKFeovMgIEudPbKu0ENFJbbz31EbEWWxv0%3D" rel="nofollow">Fundebug 支持使用 Source Map 还原真正的错误位置</a>。这样的话,开发者能够迅速定位出错的源代码。另外,Fundebug 还能够展示出错的代码块,帮助开发者更快地解决问题。</p>
<h3>Fundebug 支持哪些 Source Map 上传方式?</h3>
<p>如果希望使用 Source Map 功能的话,我们必须拿到 Source Map 文件。用户可以将 Source Map 文件挂载到自己的服务器,我们会自动下载;或者,用户也可以主动上传 Source Map。我们一共提供了 3 种不同的上传方式:</p>
<ul>
<li>前端 UI 上传</li>
<li>fundebug-cli 批量上传</li>
<li>API 上传</li>
</ul>
<p>前面两种方式都比较直观,<a href="https://link.segmentfault.com/?enc=HWqTBpvRWTG7is%2FUTHQ8kQ%3D%3D.HIIqPZO5HgVtblSun3ofjp4X4waVHYrkv7urc2a5diZ35Vdz7hgS8oZjy5LYnGl8ggoP1N3TdrZ52Jz%2FxzCZsw%3D%3D" rel="nofollow">文档</a>中有详细的说明。接下里介绍如何通过代码调用 API 实现 Source Map 批量上传。</p>
<h3>如何批量上传 Source Map?</h3>
<p>Fundebug 支持通过<code>POST</code>请求上传 Source Map,接口为<code>/javascript/sourcemap/upload</code>, 参数包括</p>
<ul>
<li>
<code>apikey</code>: 获取 apikey 需要<a href="https://link.segmentfault.com/?enc=kjlGjQ%2BTcoIUe2fgU29e8w%3D%3D.9Wz8XjtRawz0H2YP2TM9%2BR%2BmcATnvzsiMt4gzWq6CgJfWzpCnKCLfVo2R7oqwtzv" rel="nofollow">免费注册</a>帐号并且创建项目。</li>
<li>
<code>appversion</code>: 可选参数,用于配置应用版本。若希望区分不同版本的 Source Map,则在接入 Fundebug 时,必须配置对应的 appversion 属性,并在代码更新时及时更新。</li>
<li>
<code>sourceMap</code>:Source Map 文件信息,具体内容请参考下方示例代码。</li>
</ul>
<p>下面给出 Node.js 版本的代码供参考,</p>
<pre><code>const request = require("request-promise");
const fs = require("fs");
const options = {
method: "POST",
uri: "https://fundebug.com/javascript/sourcemap/upload",
formData: {
apikey: "YOUR-API-KEY",
appversion: "1.0.0",
sourceMap: {
value: fs.createReadStream("./data/app.6c20067a.js.map"),
options: {
filename: "app.6c20067a.js.map",
contentType: "text"
}
}
}
};
request(options)
.then(function(success) {
console.log("success:", success);
})
.catch(function(err) {
console.log("fail:", err);
});</code></pre>
<h3>如何清除已上传 Source Map?</h3>
<p>如果上传的 Source Map 太多,希望将旧的 Source Map 文件删掉,我们也提供了相应的接口: <code>/javascript/sourcemap/clear</code>。示例代码如下:</p>
<pre><code>const request = require("request-promise");
const fs = require("fs");
const options = {
method: "POST",
uri: "https://fundebug.com/javascript/sourcemap/clear",
body: {
apikey: "YOUR-API-KEY"
},
json: true
};
request(options)
.then(function(success) {
console.log("success:", success);
})
.catch(function(err) {
console.log("fail:", err);
});</code></pre>
<p>感谢客户大大风变科技的反馈!</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=vpla2Fl9xgvU7AOlEIaGJA%3D%3D.A%2BxQxfl4X9bPEVgSEQ%2Bjxn%2BdEEuSLIvE%2BwWLxUxKqc4%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了30亿+错误事件,付费客户有阳光保险、达令家、核桃编程、荔枝FM、微脉等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=84LoJA0lOplWmpX4lZqh2g%3D%3D.v7XaApEFMzCpDsRKrZARo%2FUpGJBAMLjT%2FVXDKakSvU4sync%2Bi3k9e13leq8fhwP4" rel="nofollow">免费试用</a>!</p>
Fundebug支持企业微信配置机器人报警
https://segmentfault.com/a/1190000021714376
2020-02-10T10:06:51+08:00
2020-02-10T10:06:51+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 为了帮助客户方便、及时地发现问题,Fundebug 支持企业微信报警了!</p>
<p><img src="/img/remote/1460000021714381" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=hoP3GJYgm%2FCkI%2BvgGDsMQg%3D%3D.dx528XkmGmH6rKGDs2dvzJt99fjuSaMLuMNkGlQS%2FY0%3D" rel="nofollow">Fundebug</a>是全栈 JavaScript 错误监控平台,支持前端 JavaScript, 后端 Node.js 以及微信小程序等应用监控。<br>如果配置了企业微信机器人,一旦应用出现错误,Fundebug 会及时发送报警信息到企业微信群。如下图所示:</p>
<p><img src="/img/remote/1460000021714379" alt="" title=""></p>
<h3>如何添加企业微信机器人?</h3>
<p>在<strong>项目设置</strong>页面,切换到<strong>报警方式</strong>选项卡,在<strong>第三方报警</strong>中即可添加企业微信报警。</p>
<p><img src="/img/remote/1460000021714380" alt="" title=""></p>
<p>具体细节请参考接入文档:<a href="https://link.segmentfault.com/?enc=9mUkp8mtA5oCyksMCZanQQ%3D%3D.hcJB9YykejGhA33tkgxAYkC7%2B%2F3kCW4rfwNnJua%2FxSkKECqF1X9pVYIO6hY6QiCj" rel="nofollow">企业微信报警接入文档</a>。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=%2BVh7nSXT%2Bm6AZluFoaFnaA%3D%3D.Q3UVe9LII1maTlO3tstovVS98LN6JWPFWavb0vGPjko%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了30亿+错误事件,付费客户有阳光保险、达令家、核桃编程、荔枝FM、微脉等众多品牌企业。</p>
Fundebug网站升级HTTP/2,真的变快了!
https://segmentfault.com/a/1190000020833996
2019-10-28T11:14:24+08:00
2019-10-28T11:14:24+08:00
Fundebug
https://segmentfault.com/u/fundebug
3
<p>作为新一代的HTTP协议,HTTP/2可以提高网站性能,优化用户体验,<a href="https://link.segmentfault.com/?enc=ZMxx0YSkY9juT%2BF2%2FJ0n6w%3D%3D.nKCxeOkXjkuqMvqYn6Yj4%2FlKUhhPPGYgu%2BiQY%2F9os54%3D" rel="nofollow">Fundebug</a>也是时候升级HTTP/2了,虽然已经有点晚了。</p>
<p>升级HTTP/2是一件很简单的事情,改1行Nginx配置就好了,但是,<strong>工程师只知道How是远远不够的,还需要理解Why</strong>,这就要求我们需要足够的事先调研(1. 什么是HTTP/2?)以及事后分析(4. 升级HTTP/2真的提高性能了吗?)。</p>
<h3>1. 什么是HTTP/2?</h3>
<p>HTTP/2是新一代的HTTP协议,于2015正式发布。</p>
<p>与其他众多Web技术标准一样,推动HTTP/2标准的依然是Google。发布Chrome的时候Google说过要推动Web技术的发展,然后它真的做到了。(<a href="https://link.segmentfault.com/?enc=YGbjGCTkFd0qxyAntBmjFQ%3D%3D.JljVS2pydNiBnkKIv4R%2FHGBT382UhcbKj27m9QeDfwd8qAj5SonSUYUuuxBD7wQynDJiLcmDGH0WXYAGFH44nA%3D%3D" rel="nofollow">JavaScript深入浅出第5课:Chrome是如何成功的?</a>)</p>
<p>根据<a href="https://link.segmentfault.com/?enc=9QPpsYGKoCkgMi76dlgk9A%3D%3D.KHbwicKbMoKYrdTElKDwuZavKzf%2FvZwk72iUcAUjb1p9hBh6I0iYmSg4cZGCZGrXm43gmnbLG%2BP%2Fhnndq%2F8aOw%3D%3D" rel="nofollow">W3Techs</a>的统计,截止2019年10月26日,全世界41.3%的网站已经使用了HTTP/2。</p>
<p>根据<a href="https://link.segmentfault.com/?enc=fg03A6uwOTtV8nrlk4hfHw%3D%3D.kh8sk%2BjUeoDkNhRybZ9Uv0Y%2BTrQVvKJzsymOl6CMvwPFusewe%2BMJQhDANnEYh1xv" rel="nofollow">Can I use</a>,绝大多数浏览器都支持了HTTP/2:</p>
<p><img src="/img/remote/1460000020834000" alt="" title=""></p>
<p>HTTP/2主要有以下几个特性:</p>
<ul><li><strong>HTTP/2为二进制协议</strong></li></ul>
<p><img src="/img/remote/1460000020834001" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=%2FuDypYeCTiYNBGbnfcq6%2FA%3D%3D.Ihnz429if%2FilWxWTNklyMKJpy3UHnW8MW11Fy3Bw5XlhtcUWZdRh1%2FlmIfLsTK0Y" rel="nofollow">Valentin V. Bartenev</a></strong></p>
<p>由上图可知,HTTP/1.1传输的是文本数据,而HTTP/2传输的是二进制数据,提高了数据传输效率。</p>
<ul><li><strong>HTTP/2支持TCP连接多路复用</strong></li></ul>
<p><img src="/img/remote/1460000020834002" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=KwW5cElKQa%2FOoDwHl9iCoQ%3D%3D.ZQLYHakC6QbHLSQgO0jksnZE0oMBWDzD7bq70bX9kl11TIZ6hyOPO13UWb1%2BVWxoIRQBqH4okm9n615f1Km3Bj5ET8uEtdnKcAFoZMSuaCkFkctNnVfVEQ%2FE%2FsxDSdm98AD49lJxLHy%2B3M6JACxomA%3D%3D" rel="nofollow">Factory.hr</a></strong></p>
<p>由上图可知,HTTP 1.1需要为不同的HTTP请求建立单独的TCP连接,而HTTP/2的多个HTTP请求可以复用同一个TCP连接。</p>
<p>要知道,建立TCP连接时需要3次握手,再加上TLS的4次握手,加起来就是7次握手,如果可以复用TCP连接的话,则可以减少这些多余的开销。</p>
<ul><li><strong>HTTP/2会压缩请求Header</strong></li></ul>
<p><img src="/img/remote/1460000020834003" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=kztCZC8EGzOlFSzjixI1Vw%3D%3D.0wmqY5UIUpadAjMGFmoOTYVR6bWikLIUBmPcdVoJcVJj9OZWxFIpbVWGPp7Bip14U2hEmoyQ%2FmZUSlwYV8q89Q%3D%3D" rel="nofollow">运维实谈</a></strong></p>
<p>如上图所示,第2个请求的Header只有:path不一样,因此压缩空间非常可观。</p>
<p>Headers压缩的算法HPACK本身似乎很复杂(其实也不难),但是算法思想其实非常简单的,假设我们在浏览器发起100个请求,它们的user-agent是不会变的,那我们为什么需要重复传输这个长长的字符串呢?用dictionary记录一次不就行了!</p>
<ul><li><strong>HTTP/2支持服务器推送(Server Push)</strong></li></ul>
<p><img src="/img/remote/1460000020834004" alt="" title=""></p>
<p><strong>图片来源:<a href="https://link.segmentfault.com/?enc=EB4LdW%2Fn8lIKMqNQkq3E1w%3D%3D.HAudwuC4MYtdgjDFoUTc4uCKh3OJq6K3fbN5Ul8Qjf9t%2BIVw1GUDcq64T1gC4Dpq" rel="nofollow">lujjjh</a></strong></p>
<p>由上图可知,当客服端向服务端请求HTML时,Server Push服务端可以提前返回HTML所依赖的css、js等资源,这样可以节省解析HTML以及请求资源的时间,从而缩短页面的加载时间。</p>
<h3>2. 如何升级HTTP/2?</h3>
<p>我们使用了Nginx作为前端页面与后端接口的反向代理服务器(Reverse Proxy),只需要修改一下Nginx配置文件就可以升级HTTP/2了,非常简单。</p>
<p>注意,在 Nginx 上 开启 HTTP/2 需要 Nginx 1.9.5 以上版本(包括1.9.5),并且需要 OpenSSL 1.0.2 以上版本(包括1.0.2)。使用<code>nginx -V</code>命令可以查看Nginx的版本信息:</p>
<pre><code class="bash">nginx -V
nginx version: nginx/1.12.1
built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
built with OpenSSL 1.1.0f 25 May 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin3-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.12.1/debian/debuild-base/nginx-1.12.1=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'</code></pre>
<p>可知,我们使用的Nginx版本为1.12.1,OpenSSL版本为1.1.0f,符合要求。</p>
<p>还有一点,虽然HTTP/2标准并没有要求加密,但是所有浏览器都要求HTTP/2必须加密,这样的话,只有HTTPS才能升级HTTP/2。</p>
<p>如果你还没用过HTTPS的话,不妨看看我的博客:<a href="https://link.segmentfault.com/?enc=dq8tyLdeQ%2BoLMBL1u2tARA%3D%3D.VrGSt4onoH63k2irzPA%2BnAr7dwEODfCYVVAQfmOperD0rcqRF1I22voWnF2%2Bw84omkiMSsJf2b4YyfEl4iiNNipTpWgVwvH17ZH7DlzTrmU%3D" rel="nofollow">教你快速撸一个免费HTTPS证书</a>,其实也很简单。</p>
<p>一切前提没问题的话(Nginx>=1.9.5,OpenSSL>=1.0.2,HTTPS),只需要修改1行配置,在listen指令后面添加http2:</p>
<pre><code class="nginx">server
{
listen 443 ssl http2;
server_name www.fundebug.com;
}</code></pre>
<p>重启Nginx,升级HTTP/2就成功了,可以使用curl命令检查:</p>
<pre><code class="bash">curl -sI https://www.fundebug.com
HTTP/2 200
server: nginx/1.12.1
date: Mon, 07 Oct 2019 00:12:53 GMT
content-type: text/html; charset=UTF-8
content-length: 4892
x-powered-by: Express
accept-ranges: bytes
cache-control: public, max-age=0
last-modified: Sun, 06 Oct 2019 23:07:25 GMT
etag: W/"131c-16da353dbc8"
vary: Accept-Encoding
strict-transport-security: max-age=15768001</code></pre>
<h3>3. HTTP/2导致Safari浏览器OPTIONS请求失败</h3>
<p>升级HTTP/2之后,使用Safari的用户发现无法登陆Fundebug了:</p>
<p><img src="/img/remote/1460000020834006" alt="" title=""></p>
<p>我们的前端异常监控插件捕获了这个报错:</p>
<p><img src="/img/remote/1460000020834007" alt="" title=""></p>
<p>可知,是<strong>/api/members/login</strong>接口出错了。</p>
<p>经过排查发现是OPTIONS请求失败了:</p>
<pre><code class="bash">curl -X OPTIONS https://api.fundebug.com/api/members/login -v
* Trying 120.77.45.162...
* TCP_NODELAY set
* Connected to api.fundebug.com (120.77.45.162) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=api.fundebug.com
* start date: Sep 15 16:38:43 2019 GMT
* expire date: Dec 14 16:38:43 2019 GMT
* subjectAltName: host "api.fundebug.com" matched cert's "api.fundebug.com"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fcfbb80ce00)
> OPTIONS /api/members/login HTTP/2
> Host: api.fundebug.com
> User-Agent: curl/7.54.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: [0]
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)</code></pre>
<p>根据curl的报错信息,可知是Header中content-length有问题:</p>
<pre><code class="bash">* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [content-length], value: [0]</code></pre>
<p>将Nginx配置文件中OPTIONS请求的Content-Length配置注释掉,问题就解决了:</p>
<pre><code class="nginx">if ($request_method = "OPTIONS")
{
add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Max-Age' 86400;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, OPTIONS, DELETE';
add_header 'Access-Control-Allow-Headers' 'token, reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
# add_header 'Content-Length' 0; // 必须注释,否则HTTP/2会报错
add_header 'Content-Type' 'text/plain, charset=utf-8';
return 200;
}</code></pre>
<p>HTTP/2中对于Header有特殊处理,这应该是导致出错的根本原因,关于这一个问题,我会在下一篇博客中详细介绍。</p>
<h3>4. 升级HTTP/2真的提高性能了吗?</h3>
<p>理论上来说,HTTP/2应该可以提高网站性能,但是实际情况是怎样呢?HTTP/2真的可以提高性能了吗?如果有的话,究竟提高了多少呢?</p>
<p>于是,我使用Chrome记录了升级HTTP/2前后<a href="https://link.segmentfault.com/?enc=yfyGCZj%2BLa%2FWlaSMDGueOA%3D%3D.3IZA5WYLrvMFTCJ9iJE9X0uMsaLZ2ZuazfIGpVIKN1k%3D" rel="nofollow">Fundebug首页</a>的加载时间,计算了5次加载的平均时间(单位为妙),如下表:</p>
<table>
<thead><tr>
<th><strong>HTTP版本</strong></th>
<th><strong>DOMContentLoaded</strong></th>
<th><strong>Load</strong></th>
<th><strong>Finish</strong></th>
</tr></thead>
<tbody>
<tr>
<td>HTTP/1.1</td>
<td>1.572</td>
<td>4.342</td>
<td>5.138</td>
</tr>
<tr>
<td>HTTP/2</td>
<td>1.0004</td>
<td>4.102</td>
<td>4.288</td>
</tr>
</tbody>
</table>
<p>可知,HTTP/2明显提高了首页加载时间,DOMContentLoaded、Load与Finish时间均有明显提高。</p>
<p>一共也就改了2行Nginx配置,就可以提高页面访问性能,多好啊!</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=CxtizlXvukaWlMneskgp8g%3D%3D.3lvmb3IKy2kV0tQIMSEVJbNc34oUCFJERFYRGYjgvkAmHGY0mOG8IeIqvqgufZngBK40CphSbW7bne2dKYzvMA%3D%3D" rel="nofollow">Module ngx_http_v2_module</a></li>
<li><a href="https://link.segmentfault.com/?enc=SCHkdZNGT0YX9WCUQLLZdw%3D%3D.rFL0eZn%2F4zvNLJZEFzAw%2BMRJkHchxXRA5MomyD6RWY0%3D" rel="nofollow">HTTP/2 Frequently Asked Questions</a></li>
<li><a href="https://link.segmentfault.com/?enc=CxlScEtvmxCEhnkrWdqvOw%3D%3D.%2B1KR9pyQxAy7WEkDrOb0hywE4LbBhAo6jBR%2FIsmIdnPM809zbCxBszgmJVP4KerK" rel="nofollow">HTTP的前世今生</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2FJZVda23n6F9N4UGb1tltQ%3D%3D.fu81gfQ3bI5%2BAvSxdBRW9hvvGxrn7KMFVkDC7rHygytNq99oZYccUXP9mV7F72Bl" rel="nofollow">The HTTP/2 Module in NGINX</a></li>
<li><a href="https://link.segmentfault.com/?enc=7%2BQvX6nNX9SssQAP6YMLWQ%3D%3D.SAofbcVC%2BlRd%2FER7vTH1xptZ%2B8VgxD%2FmMp0gPmCXRj1spKh1sAaIwvPt9OABHb1XbSfzTvG9FGO8ZGpONttlDE%2F4OAcSQtrdhGUg8%2BphshVlUPdghMHYqBBRs4eRsBC6g%2BXn8PaAx9u9zL4d7y6LxQ%3D%3D" rel="nofollow">HTTP/2: the difference between HTTP/1.1, benefits and how to use it</a></li>
<li><a href="https://link.segmentfault.com/?enc=rDYX%2Ff0kKzfDDO%2Bb7aWA7w%3D%3D.DqiORVGd1%2F8DhyULlv72RR15JtpSXkRA6v7uhN8EcaHZBLi%2FRdjdzC6dtvJotW1%2BQEd6fAT3qFZCa804538NPcGsroE5nH%2B30uXJYez3gEI%3D" rel="nofollow">HPACK: the silent killer (feature) of HTTP/2</a></li>
<li><a href="https://link.segmentfault.com/?enc=OdjV1y1XT5fJO3s0GcYuJA%3D%3D.dhEZk%2FaYzLyMjvzA%2FSbT5u87jLY67GRWXAuyfPzGxMono0KWGKlW%2F7q5Hhy9yEhb" rel="nofollow">浅谈 HTTP/2 Server Push</a></li>
</ul>
Fundebug前端异常监控插件更新至2.0.0,全面支持TypeScript
https://segmentfault.com/a/1190000020296548
2019-09-05T13:04:50+08:00
2019-09-05T13:04:50+08:00
Fundebug
https://segmentfault.com/u/fundebug
0
<p><strong>摘要:</strong> 是时候支持TS了!</p>
<p><img src="/img/remote/1460000019373421?w=900&h=383" alt="" title=""></p>
<h3>Fundebug前端异常监控服务</h3>
<p><a href="https://link.segmentfault.com/?enc=THTB8a6ygDXruFwRaE4RXg%3D%3D.6ckvKHuJRsTYgpLbXUm%2F2L%2F%2BlkMxqlggENts9QncMoo%3D" rel="nofollow">Fundebug</a>提供专业的前端异常监控服务,我们的插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括但不限于JavaScript执行错误以及HTTP请求错误。</p>
<p>并且,Fundebug支持Source Map还原,记录用户行为以及“录制”用户操作视频,帮助开发者快速复现BUG,提高Debug效率,欢迎大家免费试用~</p>
<p>Fundebug前端异常监控插件更新至2.0.0,全面支持TypeScript,为使用TypeScript的用户提供更好的编程体验。</p>
<h3>关于TypeScript</h3>
<p>想必大家都听说过TypeScript:</p>
<ul>
<li>Vue 3.0使用TypeScript重写</li>
<li>Node.js作者使用TypeScript开发Deno,一个新的JavaScript后端语言</li>
</ul>
<p>为什么很多人开始使用TS了呢?</p>
<p>因为JavaScript没有类型,而TypeScript有类型的,这样可以提高代码的正确性。另一方面,全面的类型推断意味着编辑器可以提供完备的代码补全和类型错误提醒,提高开发者的开发效率。</p>
<p>对TypeScript感兴趣的同学,不妨看看TS作者Anders Hejlsberg的视频<a href="https://link.segmentfault.com/?enc=4WwRPe4q87F8VAJLcZOz4w%3D%3D.eagEDplEcQxigxNvec%2Ft2mV9F0nc8oB9t3to7M6ZvuXUolzGeX74wA8lTERnIvrbdpd3fewoPp7hTz3DOq%2BNRdNO%2B%2FdJDA3Je6WCpYg6t5k%3D" rel="nofollow">Introducing TypeScript</a>。<a href="https://link.segmentfault.com/?enc=B4e5ePmdVR%2BNH5QLHVwp7g%3D%3D.DmrQeJ5J45ocMaM4cGexX%2BC%2F2j4p0%2BG12VS5xqFJV60%3D" rel="nofollow">Anders Hejlsberg</a>是程序员界的传奇人物,C#与TypeScript都是由他设计主导,年近60依然还在编程,但是,他的视频非常浅显易懂!</p>
<h3>全面支持TypeScript</h3>
<p>TypeScript已经在业界应用了多年,且越来越流行,因此Fundebug的前端异常监控插件也应该全面支持TypeScript了:</p>
<ul>
<li>所有的代码由JavaScript切换为TypeScript</li>
<li>严格遵守TSLint的语法规则</li>
<li>为fundebug的各个API编写严格的类型声明文件</li>
</ul>
<p>对于TypeScript用户来说,在使用fundebug的API,比如<a href="https://link.segmentfault.com/?enc=%2F3JcJQQrhTtoQjE%2BXV6yIQ%3D%3D.F69N3%2BsTB3IFh4LIBPfEhukf73Iz0OqzArNAP%2B4NOXAISll5zN1wYqgkYFRBU%2BGWN4MzMOsfWyaQI3GH8AdkKw%3D%3D" rel="nofollow">fundebug.test()</a>时,可以方便地看到类型提示:</p>
<p><img src="/img/remote/1460000020296551" alt="" title=""></p>
<p>可知,fundebug.test()有2个可选参数name与message,类型都是字符串。</p>
<h3>新增fundebug.init()方法</h3>
<p>为了兼容严格的TypeScript语法,我们新增了<a href="https://link.segmentfault.com/?enc=GOKyFRSi7JVoMgX%2BUFqGig%3D%3D.9FTock4JUMG7UVgWfqRp%2FXmH9ykz7qHGT6Y4fNCTY8jlqd53boqq8FxUtT%2FjJO61pVi6LEoXtvV%2FJwlAgfke%2Bg%3D%3D" rel="nofollow">fundebug.init</a>方法来<a href="https://link.segmentfault.com/?enc=0Ts9x79axOAkMvxbFxBX%2BQ%3D%3D.I1WleuilcX%2BJyaANRBvKdJDWT56QXAFKCOkxXtlntuWhprtToYcG468y%2BTbpISb2jKx0oYcvF0T7aP%2BbH1uUVQ%3D%3D" rel="nofollow">配置各种属性</a>,例如<a href="https://link.segmentfault.com/?enc=z95%2FZr4BCyrzyuGyZm0CLg%3D%3D.kV%2B5t%2BlaXhph10f8C42uYiNAjJ49dsfkOHWmpE3pp8Dzu%2BjvbvO17rFk8DN%2Bsu7pLLcoI0yZ29V7x4XliZhK1qy%2BZjAmc9Vf%2BgcdHLaJaUQ%3D" rel="nofollow">apikey</a>:</p>
<pre><code class="js">fundebug.init({
apikey: "API-KEY"
});</code></pre>
<p>TypeScript用户在使用全局变量fundebug来配置各种属性时,则会看到报错:</p>
<p><img src="/img/remote/1460000020296552" alt="" title=""></p>
<p>这时,使用<code>// @ts-ignore</code>忽略下一行的报错即可:</p>
<pre><code class="javascript">// @ts-ignore
fundebug.apikey = 'API-KEY'</code></pre>
<p>不过,还是推荐大家使用fundebug.init方法进行配置。</p>
<h3>fundebug.d.ts</h3>
<p>fundebug.d.ts为Fundebug前端异常监控插件的类型声明文件:</p>
<pre><code class="javascript">// Type definitions for fundebug-javascript
// Project: https://www.npmjs.com/package/fundebug-javascript
// Definitions by: Fundebug <https://www.fundebug.com>
export as namespace fundebug;
export function init(config: IConfigs): undefined;
export function test(name?: string, message?: string): undefined;
export function notify(
name: string,
message: string,
options?: IOptions
): undefined;
export function notifyError(error: Error, options?: IOptions): undefined;
interface IConfigs {
apikey: string;
appversion?: string;
releasestage?: string;
user?: IUser;
metaData?: object;
callback?: ICallback;
setHttpBody?: boolean;
httpTimeout?: number;
filters?: object[];
silent?: boolean;
silentDev?: boolean;
silentResource?: boolean;
silentHttp?: boolean;
silentWebsocket?: boolean;
silentConsole?: boolean;
silentPerformance?: boolean;
sampleRate?: number;
domain?: string;
}
interface IUser {
name: string;
email: string;
}
type ICallback = (event: object) => void;
interface IOptions {
metaData?: object;
}</code></pre>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=iIFMHlbXyt8fnSkUrn2VFQ%3D%3D.zoPhATGm9nfVDbIn0x3%2BTYKmuVUvwIffFMeWGOOEiJ%2BCOH%2FbdadwcJvA4HyPCQ31TOOEanv7xQnqLVgTlmkYgodo9JiNXCRtj1P3ev8fcsY%3D" rel="nofollow">Anders Hejlsberg: Introducing TypeScript</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=fykRxLZsM7s%2F%2BdMyx%2Bj7Ag%3D%3D.vBALLTCLTiHAupxuXGB6DWE83AEyq5gF74DForVqj88%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=TkODmQNsJDq6HYfNm3dKIA%3D%3D.yLGFTNHwm1WS%2B6vxC3tPGP3MAMFtYidR28dvVY5XWU1cGst6sT6pqfoSbxoBofh%2F" rel="nofollow">免费试用</a>!</p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:</p>
<p><a href="https://link.segmentfault.com/?enc=G%2BNaADElXjzeFlXFe1gMEg%3D%3D.T2LT5hvtsdN5ODq7Bg6ogGi72skfer1197bGL3FFWQYAHZFR%2BfBZWpnqawNKYEWzw5UIxLNFCOmYjfwUlCNnbNdplRi%2BlBIg3WrGedfsotMTuFgUzHzbw4WnNH3wBZxb" rel="nofollow">https://blog.fundebug.com/2019/09/05/fundebug-javascript-2-0-0-support-typescript/</a></p>
Fundebug录屏插件更新至0.6.0
https://segmentfault.com/a/1190000020195329
2019-08-27T08:31:15+08:00
2019-08-27T08:31:15+08:00
Fundebug
https://segmentfault.com/u/fundebug
7
<p><strong>摘要:</strong> 录屏插件的性能进一步优化,传输的数据体积大幅度减少。</p>
<p><img src="/img/remote/1460000019302055?w=900&h=383" alt="" title=""></p>
<h3>录屏功能介绍</h3>
<p><a href="https://link.segmentfault.com/?enc=7IbuUIx3npl9Cc%2BdNH99HA%3D%3D.rFuJkeUMkV6bWFzojI5Xx9K%2FSztKsb%2BxXCQFE1RwPEU%3D" rel="nofollow">Fundebug</a>提供专业的异常监控服务,当线上应用出现 BUG 的时候,我们可以第一时间报警,帮助开发者及时发现 BUG,提高 Debug 效率。在网页端,我们通过原创的录屏技术,可以 100%还原 BUG 出现之前用户的操作流程,帮助开发者快速复现出错场景。演示视频如下:<a href="https://link.segmentfault.com/?enc=9TlDIRTS%2FmaCqwEWkQLNLg%3D%3D.ZuOIWTvmPpsuv4AjpFjbLieu7UEnMjMD5rPbsQsMgd8f0METtl4xS5dq8BE9lPsG" rel="nofollow">https://static.fundebug.cn/el...</a></p>
<p>其实,我们录制的并不是一个真正的视频!算法经过优化,整个“录制”过程 CPU 的使用率非常低。和传统的视频相比,体积小了成百上千倍。Fundebug 插件“录制”的“短视频”,压缩后的体积只有几十 KB。</p>
<p>感兴趣的话,欢迎大家<a href="https://link.segmentfault.com/?enc=V8RhkUQgzO%2BzvgjZphPykw%3D%3D.8dQ8fqwd2d2f53KeRQ5RSg3aV0h8iF%2BlGW2hMXBcMlX7x7TyDK2XbycgaJFABj%2F5" rel="nofollow">免费试用</a>~</p>
<h3>尊重用户隐私</h3>
<p>录屏功能涉及到用户隐私,我们作为第三方服务,也非常重视这一点:</p>
<ul>
<li>Fundebug 默认关闭录屏功能,开发者需要的时候可以自行开启;</li>
<li>Fundebug 并不是全程录屏,只会录制 BUG 出现之前 10~20s 的用户操作;</li>
<li>Fundebug 提供<a href="https://link.segmentfault.com/?enc=yJWQfmyJ3VYGp9T%2F3MV9Hw%3D%3D.3u6zRY%2FUyYxpRJ5DSAPSHXTlhS%2FExXh4dZZL6dm9kb%2Fdmdxi%2BHrEiSSirPIUkpeAuaCplEuvTeLMdFceiZhVAg%3D%3D" rel="nofollow">敏感信息过滤</a>过滤功能,开发者可以过滤掉用户隐私信息;</li>
<li>Fundebug 重视数据安全,传输过程全程加密,<a href="https://link.segmentfault.com/?enc=8IsJR5Cfn39aMKKJ04ilRQ%3D%3D.kBFh1%2BJQPvddEXAAY%2BZ6i01A1E8kMBrhOuIFRpQnwEeeGO82DyYtlF%2BPTGqk86jvm2B4Q6hXbu1Mfyo8AbiHng%3D%3D" rel="nofollow">数据库有多重安全防护</a>;</li>
<li>Fundebug 会定期(目前是删除 60 天之前的数据)删除过期错误数据,这样既节省成本,也保护用户隐私;</li>
</ul>
<p>请大家放心使用~</p>
<h3>录屏插件更新至 0.6.0</h3>
<p>此次插件升级包括两个方面:</p>
<p><strong> 性能升级 </strong><br>我们一直在对插件进行优化,不断地提升插件的性能。此次更新我们对核心算法做了改进,将其中比较耗费计算时间和内存资源的正则匹配改为字符串匹配(KMP)算法;并且缓存中间数据来省去大量重复的计算;最后,我们还对数据的编码做了优化,同等体积数据相比之前减少 1/4。</p>
<p><strong> 新增 revedioVersion 字段 </strong><br>为了便于用户弄清楚当前插件的版本,进而顺利对插件进行升级,我们在发送的数据中新增录屏插件版本(revedioVersion)字段。该信息在报错详情的右侧展示。</p>
<h3>接入方法</h3>
<p>从 BUG 监控插件 1.7.3<a href="https://link.segmentfault.com/?enc=PSW5gMIpSvfcdqtEzJ8UIA%3D%3D.JqhAJM20sMXtPUk2dFb%2FzfhHTtQSRL269bxN90SZx1Aym87RRPoPAs8gDdY8MuUDWHXQUSg%2BgITqgZ%2Bif9Q2bg%3D%3D" rel="nofollow">版本</a>开始,我们拆分了录屏代码。如果需要使用录屏功能的话,需要单独接入录屏插件。</p>
<ul>
<li>
<p>使用 Script 方式接入</p>
<pre><code class="html"><script
type="text/javascript"
src="https://js.fundebug.cn/fundebug.revideo.0.6.0.min.js"
/></code></pre>
</li>
<li>
<p>使用 NPM 接入</p>
<pre><code class="js">require("fundebug-revideo");</code></pre>
</li>
</ul>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=Bb%2FGRyZicMyUqn9I8vwNeQ%3D%3D.8k469KwFR7pTuvjimy74DDqEXy%2BZPy%2Fm%2FihXFiOy4gsTycgg9zpmlbB5sNY1YJUrrY4twErKKFii3rhvKiEcTQ%3D%3D" rel="nofollow">澄清 Fundebug 录屏技术的几点误会</a></li>
<li><a href="https://link.segmentfault.com/?enc=1pdEwduBo8bsgD%2BS5d%2Bixw%3D%3D.lmBr1u%2BKJQDASdN8ytaJS2yrLHOozGjMC7k5QIMIChcLOJDsN6qKoTsN7QZuBTr7PsW4pcrTu09tUoFFWVJuGvaEgdSvlwRD65xi11gy4oI%3D" rel="nofollow">黑科技!Fundebug 支持可视化重现出错场景</a></li>
<li><a href="https://link.segmentfault.com/?enc=Vgn%2BKCQQvVhUwnoGi0sevg%3D%3D.bAonymqczUYZOLKELtoZMGCd0XS1fdsPwKKz%2BFSYn6CIDRgVSnwKPxr8UXpU4gkAPWvaXemVCPH%2B0eHqHHCmRw%3D%3D" rel="nofollow">Fundebug 文档 - 录屏</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=WNS8rlKgaL1EpZ%2BoW7i9ww%3D%3D.f73WZOh0TOYkk3aW5GloVIBPVt%2FRjFaB64QrlcmWO9U%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=aqnH4sGZHwseeMfl4D%2Bzcw%3D%3D.S70WaKwAiBmG33q7DmE6vLjKOPejlQvD10Op6s3CZhu6jbIIJ3eBiCBmdzg2e%2BGd" rel="nofollow">免费试用</a>!</p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=tp5JurEHJBdzq%2BTZ6JAlog%3D%3D.WaUxsnCkHvyKa495P2e7FdKWSpzKelxj2eJcmGof3VDYO8x%2F%2F4h%2FMfW%2BMXdk46aH8N0Dhg8RBMvN2GcQOkJh1A%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/08/27/release_revedio_0_6_0/</a></p>
Fundebug微信小程序BUG监控服务支持Source Map
https://segmentfault.com/a/1190000020183455
2019-08-26T08:43:19+08:00
2019-08-26T08:43:19+08:00
Fundebug
https://segmentfault.com/u/fundebug
0
<p><strong>摘要:</strong> 自动还原真实出错位置,快速修复BUG。</p>
<p><img src="/img/remote/1460000018947435?w=900&h=383" alt="" title=""></p>
<h3>Source Map功能</h3>
<blockquote>微信小程序的Source Map功能目前只在 iOS 6.7.2 及以上版本支持。</blockquote>
<p>微信小程序在打包时,会将所有 js 代码打包成一个文件,从而减少体积,加快访问速度。</p>
<p>然而,压缩代码的错误是很难Debug的,因为错误位置是这样的:</p>
<ul>
<li>文件:app-service.js</li>
<li>行号:13782</li>
<li>列号:7974</li>
</ul>
<p>这时,错误的位置信息(<strong>文件,行号和列号</strong>)失去了价值,因为开发者很难知道它所对应的源代码位置。</p>
<p>Fundebug的微信小程序BUG监控支持通过Source Map还原出错位置:</p>
<ul>
<li>文件:utils/util.js</li>
<li>行号:573</li>
<li>列号:8</li>
</ul>
<p>这样的话,开发者能够迅速定位出错的源代码。</p>
<p>在Fundebug控制台,只需要点击Source Map按钮,就可以切换压缩前后的堆栈:</p>
<p><img src="/img/remote/1460000020183458" alt="" title=""></p>
<p>如果希望使用Source Map功能,用户则需要:</p>
<ul>
<li>从微信小程序管理后台<a href="https://link.segmentfault.com/?enc=smByBDO%2BlegzsEHHp6bU7A%3D%3D.DE9CXK9q8DOsWAG3GCfFRMRYjwqOvP62mr%2F5MBrqKJOhv%2Fb%2FscDpivQoGge6bKDoGuC4z%2FJMnqNusLc7t9zGZQ%3D%3D" rel="nofollow">下载Source Map</a>文件</li>
<li>在Fundebug项目管理后台<a href="https://link.segmentfault.com/?enc=qbBwZRdbUgq7JXH4Fn5EfA%3D%3D.7ovW%2B8BdopzDYRHfs1%2FpSPVU5NSQhwVvnOPakIdkI7cFQczgmXA6nqGckciMCTglA9xYGpgqRYb99qir86kHKA%3D%3D" rel="nofollow">上传Source Map</a>文件</li>
</ul>
<h3>下载Source Map文件</h3>
<ul>
<li>登陆<a href="https://link.segmentfault.com/?enc=DQIBojvC45wyhxZWaW%2BNcg%3D%3D.FLk18q%2Fpb7nSGBG%2BqtDjQQaxgX2paKeujXVOHZAfVTQ%3D" rel="nofollow">微信公众平台</a>
</li>
<li>切换到左侧"开发"页面</li>
<li>点击链接"下载线上版本Source Map文件"</li>
</ul>
<h3>上传Source Map文件</h3>
<p>将下载的Source Map文件解压缩,仅需上传解压缩的文件中的<strong>__APP__/app-service.map.map</strong>文件。</p>
<p><strong>上传步骤</strong></p>
<ul>
<li>进入Fundebug『控制台』</li>
<li>选择『项目设置』</li>
<li>点击『Source Map』</li>
<li>选中需要上传的Source Map文件(支持上传多个Source Map文件)</li>
<li>点击『上传』</li>
</ul>
<p>上传Source Map时可以配置应用版本:</p>
<p><img src="/img/remote/1460000020183459" alt="" title=""></p>
<p>下图为已经上传的不同版本的Source Map文件:</p>
<p><img src="/img/remote/1460000020183460" alt="" title=""></p>
<p>若希望区分不同版本微信小程序的Source Map文件,则需要在接入Fundebug插件时,配置对应的<a href="https://link.segmentfault.com/?enc=pOS3h2xBEABdoMVCGZXREg%3D%3D.xULJdkJSNCLLz39NVyWKqcMwGu%2BuH0nWWJZGy9wQJ%2BfQqeuCZHdYQOwubKeuhfHuKce2f24Yt46wlSnZIbfIJkmdmF4NYJge2ic7404V9oc%3D" rel="nofollow">appversion</a>属性,与上传Source Map时设置的版本保持一致:</p>
<pre><code class="javascript">fundebug.init({
appVersion: "3.2.5"
});</code></pre>
<p>Fundebug微信小游戏BUG监控服务的Source Map功能也将尽快推出,敬请期待。</p>
<p>最后,感谢青团社的小伙伴的协助~</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=azCpKSiDyMD7mXeQIX8Keg%3D%3D.xA%2FgogoB2CCRdkMYT3H280gBsTXq8vvKB%2FURi7XD8L4atszFOYeBjSHn%2Bl5PSHyHdANETbDwJD0yu7bDp6lulQ%3D%3D" rel="nofollow">Fundebug文档: 微信小程序Source Map</a></li>
<li><a href="https://link.segmentfault.com/?enc=wIQJBAqSevnT%2F3LZWetQ8w%3D%3D.lFob8BOO5ICquqKGlYwM3zbn2UMWQqrT%2Fy2FvA1bTYc8r%2Fz%2FQ1ElpbcjFfENNZbAU9KuGLQdjvMtpbs8vi2Lxw%3D%3D" rel="nofollow">Source Map入门教程</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=54AVrBZyUziAs9TGHJkk1A%3D%3D.orqd7P7FfLdRc2moDF5MXMMWhbKGb%2B3uuKIj0Bjxsrg%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=K410MUqLZD8MOMVKmQI8Sw%3D%3D.CH0tyLvXbfgAo2u7UMTFupVn83B%2B4aRe4W2givFWcg2SEuqvhL4ybadd%2Fr0Hhx6s" rel="nofollow">免费试用</a>!</p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=U5jQJsBEzbS6e3cEgC5Ktw%3D%3D.nkoSJ19pa7%2F%2BFyY6LHzGZChhgG1cxlOMUjHdtnP6S%2FZc%2FXYKuC5syNfQ67Uh8Hx7lPhkNTLtWaRm1TGUZjXj0IhifI5ZKF%2B8YT4AZvVoyQtOUdLs3aBYoeChM71YkBtT" rel="nofollow">https://blog.fundebug.com/2019/08/26/fundebug-wechat-miniprogram-support-sourcemap/</a></p>
JavaScript深入浅出第5课:Chrome是如何成功的?
https://segmentfault.com/a/1190000020004225
2019-08-08T09:09:37+08:00
2019-08-08T09:09:37+08:00
Fundebug
https://segmentfault.com/u/fundebug
4
<p><strong>摘要:</strong> Chrome改变世界。</p>
<p><strong>《<a href="https://link.segmentfault.com/?enc=l1K6B2%2FhOxDO1bHhARuyrQ%3D%3D.6uQk4CgypjWSgFztNuxuxdyx7Ys%2BXjUsGQ9m7pLnzeCS8be6tZQ57XhkCTUv0Q0p%2Fy4i7TKLivhU1Z3SrHsGIqhvU0VBBng42pt43Lv3lPw%3D" rel="nofollow">JavaScript深入浅出</a>》系列</strong>:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=2FK3WPse4mZJiOWgP8mXzw%3D%3D.AyT2LoQTZhmeahxkhlPE3xDdsTypXxfQ2LJFErKKKD6Vt2ylBHjJ5b%2B1ALCKn46TLiVuDlRObeTI9PDjP7pF9A%3D%3D" rel="nofollow">JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?</a></li>
<li><a href="https://link.segmentfault.com/?enc=jjEp9QxT0y2cHCJ4Ymdmfw%3D%3D.UcynZXeDOOjjXHQoDVdgxMZrTjhgODAnpwLuNFfLKQQbne7cGhxwCvQqs92fE1IAMGByICE6juS2ABygYWAMF8%2FV1J%2Bk3iw5eiZntgyx97s%3D" rel="nofollow">JavaScript深入浅出第2课:函数是一等公民是什么意思呢?</a></li>
<li><a href="https://link.segmentfault.com/?enc=Kl72NKD6OW%2FL%2BqL9r2eeQA%3D%3D.1rPeJu1G%2BT9A5izI8OZ6b5qsUwSGIQpp75gqJT9PHH2uW6gVKwhy15xMlcPSMVXgNpYNmK%2FmuBV5kfGFrVbeNaOZipMje%2BnH9PBC6l9fPwA%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a></li>
<li><a href="https://link.segmentfault.com/?enc=HA9uZKNWYy9ll3yjGhISNQ%3D%3D.zxGOIbX3KiPNm0Wsy6aZsq%2B7Ixdhm%2FK7AYQ65529rpBuiBZRK%2FhoEbhyuwPuHmUbfiVmlT5yzBvS7FMyWsHEtg%3D%3D" rel="nofollow">JavaScript深入浅出第4课:V8引擎是如何工作的?</a></li>
<li><a href="https://link.segmentfault.com/?enc=pvef3gIs%2F9Vcd2WjCqBjUQ%3D%3D.c0d8nocsnsZRyRFuY5RrUjolxM%2BgMxErwGWAtF8LNCz4e%2F5oSjRjiLkEqMldkvy8n2S1toLQRmqwT7c0NzXgVw%3D%3D" rel="nofollow">JavaScript深入浅出第5课:Chrome是如何成功的?</a></li>
</ul>
<h3>前言</h3>
<p>在上一篇博客中,我聊了一下<a href="https://link.segmentfault.com/?enc=diGFDA41ElkMFYLf%2BtUpBw%3D%3D.Y27eBmacKeHK44KvUJNSbTLCjyzr8yXeQHyMNxRrxAFoIoSw%2BQnp5gygj4Ds2vXouGal5SJ5IirOL%2FMwX6rOvg%3D%3D" rel="nofollow">JavaScript引擎V8的工作原理</a>,顺其自然,接下来应该来聊聊渲染引擎Blink或者Chrome浏览器的工作原理。但是,这2个坑以后再填。</p>
<p>这次我重点聊聊产品,当然免不了涉及一些技术。</p>
<p>几乎所有JavaScript开发者每天都在使用Chrome,大家知道它是如何成为浏览器霸主的吗?</p>
<h3>Google为什么要做浏览器?</h3>
<p>其实,Google的联合创始人Larry Page和Sergey Brin早在2001年就想做浏览器,但是当时的CEO施密特一直反对,因为从头开发一个浏览器的成本太高了,不是一个创业公司可以承受的。因此,Google直到2006年,公司已经上市2年了,才开始做浏览器,秘密开发了2年,Chrome才正式发布。</p>
<p>Google真正开始开发Chrome是2006年,当时IE的市场占有率高达80%,Firefox大概是10%。自从击败Netscape之后,IE似乎可以高枕无忧了。如果那时候有人要做一个浏览器,大多数人都会质疑,还需要多个浏览器干嘛?IE和Firefox又不是不能用。</p>
<p>但是,2006年时的Web早已经不再是简单的静态页面,Gmail、Youtube、Google Maps,Facebook这些复杂的Web应用已经出现一段时间了,传统浏览器在架构、性能以及稳定性上已经逐渐不再适用了,这时正是需要一款更加强大的浏览器来满足用户与Web开发者的需求。</p>
<p>Google所做的最重要的事情,就是对成千上万的网页进行排序,所以它存在的意义是基于网页的。而一个更快、更好的浏览器,可以促进Web技术的发展,网页会越来越多,越来越好,用户花在Web上的时间越来越多,这对Google是有益。因此,Google要做浏览器,不只是想要一个搜索入口那么简单。</p>
<p>Google希望通过Chrome浏览器来促进Web技术的发展,从而让自己受益,这也不是什么秘密,Chrome团队的人都是这么说的,Google现在的CEO是Sundar Pichai,他当年发布Chrome的时候是<a href="https://link.segmentfault.com/?enc=H5KDJb12xX61mluiHJKH%2FA%3D%3D.YdnWRMDTPqOGqsTeT0f%2BYXfPFIj1y5clvIAGT%2B%2FGk0mGEW%2F5gzTg3X2M9Me%2FkguEr2JQKJUXjPn1J4Y1BojKvkJnqGYgcDKIxApSRCq4jq8%3D" rel="nofollow">这样说的</a>:</p>
<blockquote>We hope to collaborate with the entire community to help drive the web forward.</blockquote>
<p>这样假大空的话当年大概没几个人相信,但是这不重要,重要的是Google真的做到了,Chrome确实推动了Web技术的发展。没有Chrome的话,现在的Web技术大概确实得落后不少。</p>
<p>如果Google只是想要一个搜索入口,它可以收购一个浏览器,或者基于开源浏览器套一个壳,做一下账户系统就够了,再通过Google网站进行推广。国内各个大厂的浏览器都是基于Chrome的开源版本Chromium实现的,某个浏览器甚至直接打包了Chrome的安装包。</p>
<p>既然Google想做的事情是推动Web技术发展,如果沿用旧的思想和技术的话,显然是做不到的。于是,他们设计了一个多进程的浏览器架构,重新写了一个性能彪悍的JavaScript引擎V8,后来又基于Webkit做了一个新的渲染引擎Blink。</p>
<p>不妨这样说,<strong>Google与国内的搜索引擎巨头们的还差一个Chrome浏览器</strong>。后者看到的是搜索流量带来的商业价值以及重新开发一个浏览器的巨大成本,而前者看到了Web技术发展对搜索引擎本身的长远价值。</p>
<h3>Chrome就一定能成功吗?</h3>
<p>Google终于决定做浏览器了,但这事能不能做成,其实也不一定。和每一个大公司一样,Google失败的项目远远多于成功的项目,大家不妨看看<a href="https://link.segmentfault.com/?enc=kRR61TdTax3%2Fcq4RofTF0Q%3D%3D.ZVPk%2FmfviONq%2FR8fQclLGH46W0AZOiPkYlC%2FeVScIn8%3D" rel="nofollow">Killed by Google</a>里面的列表。</p>
<p>Google确实有很多非常成功的产品,比如Android,Youtube,Google Maps, DeepMind,但是它们其实都是收购来的。Chrome算是Google为数不多的真正从零开始打造出来的产品。</p>
<p>下面这张图是Chrome发布时的照片:</p>
<p><img src="/img/remote/1460000020004228?w=1023&h=371" alt="" title=""><br><strong>图片来源:Niall Kennedy</strong></p>
<p>照片中从左至右是Larry Page, Brian Rakowski, Sundar Pichai, Sergey Brin, Darin Fisher, Lars Bak和Ben Goodger,他们都是Chrome浏览器最关键人物,也都因为Chrome的成功而收益不菲。</p>
<ul>
<li>Larry Page和Sergey Brin是Google的创始人,他们一直希望做浏览器;</li>
<li>Sundar Pichai当时是Google负责产品的副总裁,Chrome也在他的管理范围之类,现在他是Google的CEO;</li>
<li>Brian Rakowski当时是Chrome的产品经理,现在是Google负责产品的副总裁;</li>
<li>Lars Bak是JavaScript引擎V8的负责人,曾长期从事编程语言的虚拟机开发工作;</li>
<li>Darin Fisher是Chrome最早期的开发者,之前是Firefox的工程师,现在是Google负责Chrome的副总裁;</li>
<li>Ben Goodger是Chrome最早期的开发者,之前是Firefox的工程师,现在的职级为Distinguished Engineer,仅次于Google Fellow以及Senior Google Fellow;</li>
</ul>
<p>照片中大家都挺开心的,秘密开发了2年的Chrome终于发布了,但是他们能想到10年后Chrome可以占有接近70%的市场份额吗?</p>
<p>下图是2009年到2019年浏览器的市场份额变化,Chrome一路飙升,而一度垄断市场的IE则刚好相反:</p>
<p><img src="/img/remote/1460000020004229" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=0JOXhLNm5QwFevweT8JVbw%3D%3D.VkniiDs8RCfMzEVWJdvWLIr9V%2BL6%2F3j3ppZ6Fj2f%2F6IybaAf0XiNcJ2s0pyfWalF5BRJzFvyQK9U81Q43yZZC8B%2BQsywG6hwxAVGR0bROQ0%3D" rel="nofollow">Visual Capitalist</a></strong></p>
<p>不妨对比一下1994年到2008年的浏览器市场份额,IE通过免费捆绑Windows把Netscape整垮了,巅峰时期的市场占有率高达96%:</p>
<p><img src="/img/remote/1460000020004230" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=BFQGWL4rGonVyh9EQgfDmA%3D%3D.Iv0xqpHJt%2BRt4ETUERHV%2BoW3s5T%2BjtWtAv6wIr7nEt3PLhBD9dAJizzcip2p62G4" rel="nofollow">Wired</a></strong></p>
<p>浏览器一直是一个硝烟四起的战场,因此浏览器市场份额的变化多少有点戏剧性。</p>
<h3>Chrome为什么会成功?</h3>
<p>Chrome为什么会这么成功呢?Google创始人Larry Page是这样说的:</p>
<blockquote>Chrome has hundreds of millions of happy users and is growing fast thanks to its speed, simplicity and security.</blockquote>
<p>Chrome很快,很简单,也很安全,所以它成功了,这是Page的观点。真的是这样吗?其实也差不多。不过还少了一点,stability,即稳定性。Chrome的产品哲学是一共是4个S:<a href="https://link.segmentfault.com/?enc=7qI6WpffrPtW6litH0i3dg%3D%3D.F5fb2Ni%2BjIj14NcHSTQ62j73R98kyr5cCmYZmjvk4A5vr2xRMgfZdBeEXi9WTUz2iev7gOVpOrwNrCP7QEePZg%3D%3D" rel="nofollow">Speed, Security, Stability以及Simplicity</a>。其实,这4个S适用于所有互联网产品,要做到话也不是那么容易。</p>
<p>说人话,Chrome究竟有哪些不一样呢?</p>
<ol>
<li>简洁的用户界面(Simplicity)</li>
<li>多进程架构(Stability, Speed, Security)</li>
<li>JavaScript引擎V8(Speed)</li>
<li>渲染引擎Blink(Speed)</li>
</ol>
<p>用户界面的Simplicity其实不难做到,现在很多浏览器和Chrome看起来也差不多,只是Chrome率先简化了浏览器的界面。这类似于iPhone发布之后,大家明白了一个简单的道理,原来手机只需要一块屏幕就够了,不需要那么多按键,后来所有智能手机基本上都长得一样了...</p>
<p>多进程架构、V8引擎以及Blink引擎都是非常硬核的技术,不是一般开发者可以做到的,就算是现在也很少有人或者公司去尝试做这个,所以现在国内外很多浏览器都是基于Chromium实现的。我想大家心里都清楚,要想这3点上超越Chrome,可能性非常小。</p>
<p>Blink渲染引擎的优化对提高Web性能也至关重要,只是Chrome刚开始用的是Webkit,我会在以后的博客中详细介绍Blink。</p>
<p>当然,Chrome所做的创新远不只这么多,我列举的4点是Chrome成功最关键的要素。</p>
<h3>简洁的用户界面</h3>
<p>Chrome已经发布10多年了,但是它的界面其实没怎么变过:后退图标,前进图标,刷新图标,合并的地址栏与搜索框,书签图标,登陆图标,设置图标...Chrome的界面非常简洁,没有任何多余的元素。</p>
<p>2009年的Chrome是这样的:</p>
<p><img src="/img/remote/1460000020004231" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=O1AlJEqIxceRB62iiFpHjA%3D%3D.IrDNjZIorL2e88G5eT%2F0SsId8OjSibOQyQUmf2Na6IluPYXTC0ZN6vo3EtVxCart" rel="nofollow">Gmail in 30 seconds</a></strong></p>
<p>2019年的Chrome是这样的:</p>
<p><img src="/img/remote/1460000020004232" alt="" title=""></p>
<p>Chrome发布时,IE8也差不多在同一时期发布,但是它的界面就没那么简洁了:</p>
<p><img src="/img/remote/1460000020004233" alt="" title=""></p>
<p>通常,用户应该不会去点击“页面”、“安全”、“工具”等选项,其实它们完全可以隐藏起来。Chrome的很多选项都是隐藏在设置选项里面,其实更加科学。</p>
<p>Chrome是第一个将地址栏与搜索框合并的浏览器,合并的框被称为Omnibox,用户既可以输入地址,也可以搜索关键字。当用户输入时,Chrome还会进行实时推荐用户可能要访问的网页。</p>
<p>Chrome还把书签栏给隐藏了,这对于重度书签用户(比如我)来说带来一些不便,但是这也让界面又简洁了很多。很多浏览器的书签栏不仅没有隐藏,还会添加很多莫名其妙的默认书签,甚至很多软件安装时也会给浏览器添加一些书签,而这些书签其实很多用户都不会访问。</p>
<p>合并地址栏和搜索框,隐藏书签栏,这样做不只是让用户界面更加简洁,还可以培养用户的搜索习惯,让用户不在需要记住特定的网站。</p>
<p>Chrome与IE8的Tab位置是不一样的,Chrome的Tab在上面,而IE8的Tab在下面,这个区别似乎没那么重要,不过也没那么简单。Tab是Chrome用户界面最重要的元素,每一个Tab使用独立的进程,Tab可以拖拽出来作为独立的窗口,相当于一个独立的应用。</p>
<p>Chrome的设计哲学是"Content, not Chrome",因此它们Tab置顶,把一切可以省略的东西都去掉,比如搜索框、状态栏、书签栏以及各种设置的快捷方式,尽量让每一个Tab看起来像一个独立的应用:邮件、视频、社交或者购物等,不要让多余的浏览器元素影响用户体验,让用户专注于Web应用本身,让Web应用越来越重要,这不不正是Google的阳谋吗?</p>
<p>Chrome的产品哲学与iPhone以及微信本质是一样的,都是极简主义,这个地球人都知道,但是没有多少产品可以真正做到。为什么呢?因为要做到极简主义,需要<strong>深刻思考用户需求以及产品价值</strong>。</p>
<h3>多进程架构</h3>
<p>Chrome的每一个Tab和插件,都使用独立的进程。这样可以<strong>提高浏览器的性能、安全性以及稳定性</strong>:</p>
<ul>
<li>充分利用多核CPU,不同的进程可以使用不同的CPU核运行;</li>
<li>便于限制Tab与插件进程的权限,减少安全隐患;</li>
<li>当某一个Tab的页面崩溃了,不会导致其他Tab崩溃,整个浏览器还可以正常使用;</li>
</ul>
<p>多进程架构借鉴了现代操作系统的设计思想,浏览器不再是一个简单的应用,它是一个平台,可以用于独立运行各种各样的Web应用。</p>
<p>使用Chrome的任务管理器,可以查看每一个Tab和插件进程所使用的CPU、内存已经网络。这样可以帮助Web开发者优化代码,高效利用计算机资源。</p>
<p><img src="/img/remote/1460000020004234?w=479&h=292" alt="" title=""></p>
<p>既然多进程架构有这么多好处,那为什么以前的浏览器采用单进程架构呢?因为IE、Firefox等浏览器诞生时,Web还非常简单,大多是静态页面,单进程就够用了,而且当年也没有什么多核CPU。</p>
<p>从单进程架构切换到多进程架构是一个非常复杂的过程,Firefox从2009年到2017年花了整整8年时间才完成切换。从这一点来说,Firefox落后了Chrome接近10年。这倒不是因为Chrome的工程师特别厉害,而是因为Chrome从一开始就设计了多进程架构,没有什么技术债。</p>
<h3>JavaScript引擎V8</h3>
<p>Chrome的性能优异,很大程度上要归功于他们的重新的开发的<a href="https://link.segmentfault.com/?enc=rv%2BpfI8QemDHwMTIOwCOdw%3D%3D.tiznmyRYQpVwFBGpCMU80tRtrJU5jUJhKsUlQGq2vjUxjLXATge7e4FV3FRptprytCZkvDeEl4JtgLx2Y%2Fl9Rg%3D%3D" rel="nofollow">JavaScript引擎V8</a>。V8引擎可以将JS代码编译为高效的汇编代码,同时还要负责执行代码、分配内存以及<a href="https://link.segmentfault.com/?enc=3T8tg9FmIp%2FLJW9JPd4YcA%3D%3D.EaEXVbudjt0MeTpRxjYOFG4MMcObR8a1fNmzKF38tXUC1kN7f%2Bgd%2Bztxq3fnkF0PGDNgZ2TT1%2F1xGHbw%2BzCrqQeBurTOSx0Htmvhr5qxGxI%3D" rel="nofollow">垃圾回收</a>。</p>
<p>V8引擎的命名灵感来自超级性能车的V8引擎,敢于这样命名确实需要一些实力,它性能确实一直在稳步提高,下面是使用<a href="https://link.segmentfault.com/?enc=JM1THu%2Fc2uxQqFuUhbjDgQ%3D%3D.%2FtW4ZvK64yzcyzbKZ9FHgtLG2p%2F1gvUiRZyx%2B%2BIpCbXx0SP%2F6kUwHKjeDznZbK%2FR" rel="nofollow">Speedometer benchmark</a>的测试结果:</p>
<p><img src="/img/remote/1460000020004235" alt="" title=""><br><strong>图片来源:<a href="https://link.segmentfault.com/?enc=Q3qOEFMeHAayBLjSjY7n7w%3D%3D.PlSbnG4dVfPoG4pdtZ9r1A%3D%3D" rel="nofollow">https://v8.dev</a></strong></p>
<p>JavaScript是动态的,且没有类型,这会给V8引擎编译JS代码时带来很多麻烦。不过V8引擎可以记录代码第一次执行时的类型信息,当代码第二次执行时,则可以根据记录的类型信息生成优化的汇编代码。另外,V8引擎还会为Object生成动态的hidden class,用来记录Object的结构,以提高属性的访问速度。</p>
<p>V8引擎的垃圾回收算法也非常强大,可以大幅减少内存使用。最近有人对比了一下3中不同类型的JS引擎JavaScriptCore、Hermes以及V8在React Native应用中的内存使用情况,发现V8的内存使用量明显低于其他引擎,且非常平稳:</p>
<p><img src="/img/remote/1460000020004236" alt="" title=""></p>
<p><strong>图片来源:<a href="https://link.segmentfault.com/?enc=ZqVSTcM0dgECwdUH7%2BpruQ%3D%3D.QnnFmWHM6DO3LI%2Bnu7Y5%2BiyclF484InND4I9jnIAc1kMc7owgD5WRQ8Twxpt8ejQfUuKA0RMNJXP8spsVjRqw77AOtpqs6imEL5RipkUa5cOVBLtXrUvGP01xlRjZ14z" rel="nofollow">Bhaskar gyan vardhan</a></strong></p>
<p>关于V8引擎以及垃圾回收算法的技术细节,大家可以阅读我的博客:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=4G6V3BP6ZRgEufVCa%2BS5QA%3D%3D.c5AFA4sGrNU9oqlSLUUx%2FzEtYjBj%2FftMQFoRmD0sIfkO84gWvrxWvogJsXxziDAbrF2rIQq2oCn8sjtNPojRWA%3D%3D" rel="nofollow">JavaScript深入浅出第4课:V8引擎是如何工作的?</a></li>
<li><a href="https://link.segmentfault.com/?enc=G6hUHazaitjrw0JgaeDH0A%3D%3D.e09H1VMWvmwKhzg1wnXeSsxkOvq509p1%2FJw18x8QTnHpljyWQMTqymkvXO5Rwe2mPlvX1SLf%2FdESt9rdyPNjSyY2afbkNsjp7ZEkH5SFueA%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a></li>
</ul>
<p>V8引擎不只是让Chrome变快,它也让JavaScript变得更加强大,让JavaScript生态系统变得异常繁荣。Node.js也是基于V8引擎的,因为有Node.js,才有了数量庞大的NPM模块,才有了各种各样的JavaScript开发框架和工具。</p>
<h3>Chrome会成为下一个IE吗?</h3>
<p>也许是树大招风,最近批评Chrome的声音越来越多了,有人甚至说Chrome会成为下一个IE6。个人觉得这个有点危言耸听。</p>
<p>Chrome从一开始就是开源的,"Talk is cheap, show me the code",如果实在对Chrome有啥特别不爽的地方,其实可以去改代码,或者fork一个更好的版本。</p>
<p>Chrome从一直是尊重技术标准的,它在发布的时候就通过了<a href="https://link.segmentfault.com/?enc=KXs9hD5gEVxQeBYuaCa8ww%3D%3D.WVtO1jPhQ22ErdKWVqctSk4uwW1gRJpxiUUZf9eZhrc%3D" rel="nofollow">Acid</a>测试,更重要的是,它一直在推动HTML5、CSS、ECMAScript、HTTPS, HTTP/2, WebAssembly, Service Workers, Source Map等Web相关技术标准的发展,大家可以在各个标准提案中看到Google工程师的身影。</p>
<p>有人说Google工程师最大的问题就是喜欢提新的技术标准,但是有标准比没有标准要好太多了,国内各个大厂小程序做了快3年了,至今连个标准都没有,各玩各的,这样做导致整个小程序行业一起加班,一起重复劳动。最严重的问题在于,没有标准会制约小程序的进一步发展,大家无法给用户提供最好的产品。</p>
<p>开放繁荣的Web符合Google的长远利益,因为Google是靠Web广告赚钱的;但是Web对于Microsoft来说一直就没有太大商业价值,因为Microsoft卖的是操作系统;按照吴军老师的基因论,IE之所以失败是Microsoft的基因决定的,而Google的基因决定了它必须把Chrome做好。</p>
<p>从目前的情况来看,Chrome依然会保持简洁的界面,性能也会一直提高,这样的话,用户和开发者也没有多少动力去换浏览器。我已经用了7年Chrome了,未来还会继续用下去,那你呢?</p>
<p>关于JS,我打算花1年时间写一个系列的博客<strong>《<a href="https://link.segmentfault.com/?enc=J%2B5n8x1MX3OYm5v5qBtlsQ%3D%3D.yF9UU8fHRTWFm4oOnd4HtyWF8tnr8PD4%2F0T1ALS%2BKWAmvhjWLsyhcBnrWTh1f6BqGL57xuQfcWt1yoUyUXQYaxXgzYmowyyeiZsT61PaCQs%3D" rel="nofollow">JavaScript深入浅出</a>》</strong>,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。欢迎添加我的个人微信(KiwenLau),我是<a href="https://link.segmentfault.com/?enc=rEbKIEHPVvsksGVRIqpalw%3D%3D.89hCf2wbx7bxUNkWfb52iJ2ouQPQ6DoadDcTWIBCXZc%3D" rel="nofollow">Fundebug</a>的技术负责人,一个对JS又爱又恨的程序员。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=f%2FQfPZYtH%2FlV3nBwzCtv1A%3D%3D.%2FDkDaauOwSSeED4c4%2FHXrbE%2FdRLPjdauVka7CL4GIbmUU357HldUkFgYfimuFDurVQLDAJB6eLaLe4Wi3MejeA%3D%3D" rel="nofollow">The Google Chrome Comic</a></li>
<li><a href="https://link.segmentfault.com/?enc=mwQeLyg4H1PK1KA4MgGVFA%3D%3D.jwcjLqrdcpJ6C9KlsZ%2F1ZzNCuNwC1lLvmQqx0pbFo8%2BhE%2ByggHky0dn4csZvcI7X" rel="nofollow">Inside Chrome: The Secret Project to Crush IE and Remake the Web</a></li>
<li><a href="https://link.segmentfault.com/?enc=vLh8LLtiEsHshWdBnCFhFA%3D%3D.rq7L9exLNq4NwdHRPLmzub%2BoS3zqZ1al9Jo2x70%2BD9%2F64zBaPgkHC5fbqEp7llkR9tV9dP%2FZeR5T3mmbLouPsMGShADoKgbmZAWwOE%2BjscU%3D" rel="nofollow">From PM to CEO: How Sundar Pichai’s Background in Product Paved the Way for Becoming CEO at Google</a></li>
<li><a href="https://link.segmentfault.com/?enc=PQijF5vEzXgVH8YJGsum8Q%3D%3D.Y3GVILA2VkWidsh3v%2FD9S5upO9pNm7oIE%2Bby%2BLVxs6tbbS7syatliMqw42%2FfX820OWlX4Qt9%2BcTUKaAXTaITO45oGeEzzOxki1wMYtKqFDm4N6En%2FzjVlI7yALJ%2FmqgkGcR7ZmUIBlo0qnPjcxKiVA%3D%3D" rel="nofollow">Chrome is turning into the new Internet Explorer 6</a></li>
<li><a href="https://link.segmentfault.com/?enc=Aq1kQ39mUYmujuomYgDDFg%3D%3D.VBcDdI%2FWlDVbfdNIir1A%2B5lVDmovf4oogKgn9lnfe0Vl0WIglEohyzKRvGdFnISG" rel="nofollow">From 0 to 70% Market Share: How Google Chrome Ate the Internet</a></li>
<li><a href="https://link.segmentfault.com/?enc=gN5lauuw2FlbCEmaIly4Fw%3D%3D.Dj%2Bf3ywfabOi0WPvlIxTluZTcf6doQ5NRFavg4z095g0itSXZJkya7IGsnVV02l%2BZ%2B9MStPuqG%2BqeKS4gVOVTJjVRR3UdqyjQhslxM9%2B7j0%3D" rel="nofollow">Google Chrome launch</a></li>
<li><a href="https://link.segmentfault.com/?enc=p4nlL3JM0Xu6MvMm1CPq1Q%3D%3D.CbbfCVWOMByyP9iTOccF7cu7CC2HltTi2TMYHjvf0jMiUX%2FobstzbRJimuCtcGk%2BcZkftoY33WkDwM6L860cIjX7bPOpOZBstfR%2FU5RK29s%3D" rel="nofollow">Modern Multi-Process Browser Architecture</a></li>
<li><a href="https://link.segmentfault.com/?enc=BVUpleGbRsn61DL%2BAk2gWA%3D%3D.%2FY%2Fmf94Ladll%2F9u9rjmnkv9sl%2FxAwCQwhWDkOqxmIks0pVgOCgLSbH07NCgpb7SKaKbQ0pm3Kt3o7x9Kt8uuVmaunkvJTqDn726fve%2BQLKs%3D" rel="nofollow">Photos: 10 years of Google Chrome</a></li>
<li><a href="https://link.segmentfault.com/?enc=fD4QQoePtndkF6G8wXVi2Q%3D%3D.xVBOM6P0j%2BA2VAeKQNVBz4%2BzrKHdqrDDzwIML%2BxfkMc3ZmZnE6Vkq3jM9NfcDfFNLK2cFo%2Bgx4rDKs%2FDKlPezfCsHrB%2FEWMFajnrRWDsdHI%3D" rel="nofollow">Timeline: The 30-Year History of the World Wide Web</a></li>
<li><a href="https://link.segmentfault.com/?enc=3ZxqWUVmuoeoscnD%2BwDkWw%3D%3D.i%2F9iZ7XSqyvC38hguiJtAeKYkI4h4qtuErhB03KI4KKpnGe2nq2WlTH9Tkz4rWx8%2BQwxLQLwfyrvkRENq6J039JmfKz%2BhealVBKxMnqzIVQ%3D" rel="nofollow">How we designed Chrome 10 years ago</a></li>
<li><a href="https://link.segmentfault.com/?enc=JKgTgvKtGU8pCvyU21mYzA%3D%3D.Q3mzq9O%2BvcQ5bhUTu8dmrkRc2SqSlM6ERXVoRe5bkuPLZQgaCT6H31XX9ZkAU8i5TADpDcdUWxtubkfW6tHtvw%3D%3D" rel="nofollow">The Chromium Projects: Core Principles</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=atXf641Y5uWHLJZu2bmaPA%3D%3D.2QI8VL1z%2FkGoPpyvmbPdlnsWHuxmAp3e5eZZ4%2FFADb8%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=NHS8%2BH2MyVWE7mQG8m6A0A%3D%3D.E%2BLrKYXFARtsB4shtfx3KCZRVYbphXd5pRqY8wY%2Fc%2F1jLZxNq%2BF70I33pwLqNPJk" rel="nofollow">免费试用</a>!</p>
<p><a href="https://link.segmentfault.com/?enc=28lQfPzl3GrO0IJ0invRHw%3D%3D.USeoTG8HwyEOJjc71smJuJcb52C%2BUDDJvijo4FRvrG0JweCI%2BpY7U5nP3RD8Tbqb" rel="nofollow"><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=u0ugp3d8bupRvVTnx1QmMg%3D%3D.dMPqigmJ5Syl9VkVeSazEMf9Z8B5%2B327THVSGCqqsa814KAGKV0MRnERfHQljo%2Fxk%2BHhtrvRPoxsHJEjMRv4ww%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/08/08/how-does-chrome-succeed/</a></p>
Fundebug 微信小游戏异常监控插件更新至 0.5.0,支持监控 HTTP 慢请求
https://segmentfault.com/a/1190000019971755
2019-08-05T10:41:02+08:00
2019-08-05T10:41:02+08:00
Fundebug
https://segmentfault.com/u/fundebug
0
<p><strong>摘要:</strong> 支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG。</p>
<p><img src="/img/remote/1460000019971758?w=900&h=383" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=jGBzc6SUz6VIMgf2TYuxEw%3D%3D.Byj%2FLP0R3lstMDk4IHCU4ggb%2BknQhMZcXzW7Ajh9toc%3D" rel="nofollow">Fundebug</a>是专业微信小游戏 BUG 监控服务,可以第一时间捕获线上环境中小游戏的异常、错误或者 BUG,及时给开发者推送报警,帮助您快速修复 BUG。</p>
<p><a href="https://link.segmentfault.com/?enc=wIGKamqaMd2fIypR8ICuoQ%3D%3D.t9bS5YL45w%2F3vmUGr8u%2Fa7Q%2B%2FbCwqhWVRuJCn%2BP4mMs%3D" rel="nofollow">Fundebug</a>的微信小游戏BUG监控插件更新至<strong>0.5.0</strong>,新增<a href="https://link.segmentfault.com/?enc=vJL%2BeaxcUcVg7i04nD4tzg%3D%3D.qbib671KvjsSqzMILFzJoJ18r7pi0EchJkEX2HZnYbcpi6UBJ8BOrsjcC1S5DMkYk4QMZ2DUSlhbSRvY4FGou6VBSaghphuuqekANhAHjzs%3D" rel="nofollow">httpTimeout</a>配置选项,支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG,请大家及时更新!</p>
<h3>监控 HTTP 慢请求</h3>
<p>Fundebug 专注于 BUG 监控,暂时无意于提供全面的性能监控服务。但是,当 HTTP 请求过慢,导致用户体验很糟糕时,也可以理解为一种广义的 BUG。HTTP 请求的性能问题,可能是代码的算法不够好导致的,有可能是数据库的索引不合理导致的,还有可能是其他原因,这些都是技术层面的”BUG“,需要开发者及时处理。</p>
<p>当然,监控所有 HTTP 请求的响应时间不是我们 Fundebug 需要做的事情,因此我们只支持监控慢请求。用户只需要配置一个阈值<a href="https://link.segmentfault.com/?enc=j3g8KT48E0cYG3HGTJiPNQ%3D%3D.jWdTf4r%2BAl1LMqHKWuGEds%2FuWGDAO5woIvaN92TJCkDBlKZUEnRjVh7hZ1gUV7RLxk5wdyYH0ErQPKxux3CSbOeRX6Pk41sh%2BZoIODUk0Dk%3D" rel="nofollow">httpTimeout</a>,所有响应时间超过阈值的 HTTP 请求都会上报的 Fundebug,这样可以帮助开发者发现一些慢请求,及时优化性能。</p>
<h3>微信小游戏配置选项 networktimeout</h3>
<p>根据微信小游戏的开发文档,<a href="https://link.segmentfault.com/?enc=62nNqPccf7nF9dybKUDcqA%3D%3D.6uqSYP9KUnmHNtxfXf5GeHdHBe2VXAzX1K1%2BA%2FJ2yH0%2Fx6B%2FlcySftU4GieFAybvcviUNLasrVaDMz9XArvtL7bMAfbZk8dQBW2qS8RSPwFn9FxlGCTLUzbfk9wsNLSPDRLw7RaNBXwIgnpAaUdp85X2h5Wo1VKJwn5qNyY1AUc%3D" rel="nofollow">网络请求</a>的默认超时时间是 60s,用户可以通过配置<a href="https://link.segmentfault.com/?enc=%2F9qLdo0LRQ90ojLzzp4D0w%3D%3D.8y06QU9RGeDUYJGVbnQrI0qhvgsd8K0P%2Bh8BijLVxH8DVCv4p6VND6H3GfoGY5aK7QKhe4FPZwzPYGI5htgz2U%2FVIaEYjOh4RdfXfgb7wMk%3D" rel="nofollow">networktimeout</a>来自定义。如果某个 HTTP 请求的响应时间超过这个阈值的话,则该请求会出错,Fundebug 也会上报这个超时错误。但是,networktimeout 不能配置的太低,否则超时的请求都会失败,这并不合理。所以配置 networktimeout 并不能实现监控 HTTP 慢请求的目的。</p>
<h3>httpTimeout</h3>
<p>监控 HTTP 慢请求的正确方式是通过 Fundebug 的配置选项<a href="https://link.segmentfault.com/?enc=j5oFnjGzG1tFofl72OKcYg%3D%3D.4Vz%2BgvbKLbDgP%2FAmMKhX5rIH6ewNODuwujaUsm3RdvYyfd4Nj0bfrdiabh%2Fe%2BLkYe7hZYQ8DesUUpYeprTcP91bizv9lN86%2B0KK37eK%2FTtA%3D" rel="nofollow">httpTimeout</a>来实现。</p>
<p>httpTimeout 类型为 Number,单位为毫秒(ms)。</p>
<p>如果你希望监控较慢的 HTTP 请求,则可以通过<a href="https://link.segmentfault.com/?enc=hWkd5KsIq9vVqxi%2FAbbWDA%3D%3D.P%2FGu%2B9nmPK%2BvvWLYG9Ny1vZzceRSAayQgJMMLblKgcdnJt3vvpaU%2Ft%2BwNeyjjFd9ZQqpZiQfC%2BYnA9JPdVJErIEkp2rxvk3PpxXKViX%2BDkU%3D" rel="nofollow">httpTimeout</a>配置阈值,比如 1000:</p>
<pre><code class="js">fundebug.init({
httpTimeout: 1000
});</code></pre>
<p>则所有响应时间超过 1000ms 的HTTP请求都会上报到 Fundebug。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=DewI3Y%2BCyGc1s1qoMKsmog%3D%3D.w9ju9W1hsusXbPocj0%2BeYs%2Fu3GFAnVFCBKsABCAYyrHBiMiEoBLEqvu9LRTnOHPnbDMxWJc15JeU0f2OnEFojwpsPoQey4Aa7PFnFKTYIec%3D" rel="nofollow">Fundebug 文档 - httpTimeout</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=lRUYfGtZlz0q61bKMV3qWw%3D%3D.Ya3GAP2CFKNvw3yIaAcLW%2FaYjySzXasSY96eWjcy4PY%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多知名企业。欢迎大家<a href="https://link.segmentfault.com/?enc=jJJiyz5FONCrNMtCn4A0OQ%3D%3D.SmI0X6Pu8ReBT684sy9WWgjai%2BwMwCh8Qjx%2FEmIL7Zx29uvG5IHFQrOK%2BQAKUKLZ" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=HYhDDTm%2FR8aEBfGNaC57Vg%3D%3D.H0refrj6SZK9klOw%2B1aMxaP%2Bs0Kc0L6BzXmxqgJI8q0%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=6Q%2BI%2Bvw0IrlcY35wNobSgg%3D%3D.eUDIajcGn3SQAxwUHyMICVkAOY%2FWxU7D4O6jHpGLcLdL8iCdiSXSUzOwQmTC%2FWQqeL79uMAoLxbRjCv1PBFcNg%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/08/05/fundebug-wegame-0-5-0/</a></p>
Fundebug后端Node.js插件更新至0.2.0,支持监控Express慢请求
https://segmentfault.com/a/1190000019921983
2019-07-30T17:38:28+08:00
2019-07-30T17:38:28+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 性能问题也是BUG,也需要监控。</p>
<p><img src="https://static.fundebug.cn/fundebug-nodejs-upgrade.jpg" alt="" title=""></p>
<h3>Fundebug后端Node.js异常监控服务</h3>
<p><a href="https://link.segmentfault.com/?enc=AXytjHj2bIrc7MGQPQ4sMA%3D%3D.vTfEmdW5rZNxx%2FUgtfjWU76hBwDcXbXdAE8dv%2FSfV2Q%3D" rel="nofollow">Fundebug</a>是专业的应用异常监控平台,我们Node.js插件<a href="https://link.segmentfault.com/?enc=a7mjGdrWC8IYwlZtNsE%2BvQ%3D%3D.ttemyS7LCRakr9je1%2BsP1HoUHwLrngZL0g264psMOTdmORVfCGH%2BZKJ0PDvXl3ZL" rel="nofollow">fundebug-nodejs</a>可以提供全方位的异常监控,支持<a href="https://link.segmentfault.com/?enc=DpvGJX266JKcozdMAwKPJA%3D%3D.HtHx7vEGTiRh%2FxZTGo%2FkwhgPuk7Q5nefnlv%2B0HpUmaNOdsjx3LkXrMKjbFMqg%2FxIkIdFDAkNNWGgJdK%2BHaycZM7Dke9tHIbF2TiWoSkiMts%3D" rel="nofollow">Express</a>、<a href="https://link.segmentfault.com/?enc=5EsgE1mBZu0eEI%2FTHKeCcA%3D%3D.YlFc62myeKj5crmmw4vMUs8Hm11ypPJiuxKdT%2B5WBvM%2BxDb3gQrsH6xcCTmbO2wJVc%2FrHPQv3bXfysieBCS7%2Bw%3D%3D" rel="nofollow">Koa</a>以及<a href="https://link.segmentfault.com/?enc=clrrVToPPjWuWROboGP9%2BA%3D%3D.aw5lpH9B2aroff5vTAlPNXJCM33z182XH%2FC7tPI%2FtHpxiV%2B8T1gNWETyKfBYF%2BvUSyXoTb%2FbCF4eiybpXeB%2FjQ%3D%3D" rel="nofollow">Hapi</a>框架。</p>
<p>从用户的角度理解,性能问题某种程度上也是BUG,它可能是数据库的索引问题,可能是代码算法问题,也可能是业务逻辑的设计有问题。为了帮助大家快速定位性能BUG,fundebug-nodejs插件更新至0.2.0,支持监控Express慢请求。</p>
<p>不过,Fundebug暂时无意于提供全面的性能监控服务,我们将继续专注于BUG监控。</p>
<h3>监控Express慢请求</h3>
<p>监控Express慢请求,需要配置阈值<a href="https://link.segmentfault.com/?enc=Mw4Upn7prpVE7qbk9jKHvQ%3D%3D.fU7GDuDkb%2B60d9HJyyQjMtoElWlzqgt4KI0%2BMym876EzUVgcdOhd3eRdCEmD%2By8W5hGYixc9vwaBSlDPMW5PV%2FRlVaerxBwNcKeF6KtxnpI%3D" rel="nofollow">httpTimeout</a>,并且添加ExpressTimeoutHandler中间件。</p>
<pre><code class="js">fundebug.httpTimeout = 1000;
app.use(fundebug.ExpressTimeoutHandler());</code></pre>
<p>注意,Fundebug的慢请求监控中间件<strong>ExpressTimeoutHandler</strong>必须放在其他中间件之前。</p>
<p>这样,所有花费时间超过阈值1000ms的请求都会上报到Fundebug。</p>
<h3><a href="https://link.segmentfault.com/?enc=JRekaOec2RSt6fJ9pz%2B93w%3D%3D.dRmMiuyoWt1SryAK89yEEpy0wjM55GYSUUC7XXNzRO61vBiIAiRRewF%2BN6GVztWky6FxtnTfmiMz441h3YSO4g%3D%3D" rel="nofollow">fundebug-express-demo</a></h3>
<p>关于Express如何接入Fundebug异常监控服务,不妨查看我们的Demo项目<a href="https://link.segmentfault.com/?enc=9DbJh3csXy%2FAxXnpd1bLcw%3D%3D.%2FeEgOGDYKfJWI4F7z5pYa7vmzE9Twwbx%2BhaNWj8%2FUlhfVJrkr7MvPv4IUis1Xh0RezRCLitKNTMVF0vW%2BZxBwg%3D%3D" rel="nofollow">fundebug-express-demo</a>。</p>
<pre><code class="javascript">const express = require("express");
const app = express();
const port = 5000;
const Promise = require("bluebird");
const fundebug = require("fundebug-nodejs");
fundebug.apikey = "APIKEY";
fundebug.httpTimeout = 1000;
app.use(fundebug.ExpressTimeoutHandler());
app.get("/error", () => {
throw new Error("test");
});
app.get("/timeout", async (req, res) => {
await Promise.delay(1500);
res.sendStatus(200);
});
app.use(function(err, req, res, next) {
res.status(500);
next(err);
});
app.use(fundebug.ExpressErrorHandler);
app.listen(port, () => console.log(`Example app listening on port ${port}!`));</code></pre>
<p>其中,<strong>ExpressTimeoutHandler</strong>必须放在其他中间件之前,而<strong>ExpressErrorHandler</strong>必须放在其他中间件之后。</p>
<p>Fundebug所捕获的超时请求如下:</p>
<p><img src="https://image.fundebug.com/2019-07-30-express-timeout.png" alt="" title=""></p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=s%2F1DTXdkNadiTZzu7H%2BfZw%3D%3D.xhbMmTZRhlGTdbJtj8VxV%2FCaYpeoNgvkF9SHTjjYXdSmMs64QVfB6LeVc5ue2O9eCT1shvDPtpJDkqcJ%2B8ZZyDrq7ZVwGeiuzhmALKEvx1s%3D" rel="nofollow">Fundebug文档 - 监控Express</a></li>
<li><a href="https://link.segmentfault.com/?enc=ZLiKoPpUXI3IbhnJQJvDdA%3D%3D.eX7cLIpI5YfE5UE3isTGg34RRbrxJMnJ4FIguZzLLF%2FdHNSs21o1WapMouevZULUjYyBLsKP5Zja%2BCUB4XTt8Usw%2BO9qsmKd%2FUQzWvGvyj8%3D" rel="nofollow">Fundebug文档 - httpTimeout</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=ekS5y1pgjuIf8N%2F%2BwSfDkw%3D%3D.pFau%2F5KsRG%2F0kL8ntE%2BQuombsbu%2Ffo496jZzeYyz9Is%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多知名企业。欢迎大家<a href="https://link.segmentfault.com/?enc=gZ8pjU%2FylwMki7PalVPCDg%3D%3D.g3ZBsqZlf0WC9ayXu2RMBJoEKsJAajp9RzB3pV8n6S0AmXVyiM5TUuhhlrfyx%2FEk" rel="nofollow">免费试用</a>!</p>
<p><img src="https://static.fundebug.cn/wechat_slogan.png" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=XHRV5PV8z91dwW23L4y1uw%3D%3D.a77iDtQRUCoCo%2F4KEI0c2TNCjKZZY1pPWZ1gj1WFgpc%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=fjIATf%2FPCXyb33dt8JLYvg%3D%3D.5NvGgqL38oEJKox%2BMLN0PqNiQpUzFBX61%2FcKOrWkm5SOFByQy3YnnoTB1EOcE9sawSOp3fAVfLmvWFYTaifxRQ%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/07/30/fundebug-nodejs-0-2-0/</a></p>
Fundebug:JavaScript插件支持错误采样
https://segmentfault.com/a/1190000019819908
2019-07-20T10:25:18+08:00
2019-07-20T10:25:18+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><img src="/img/remote/1460000019373421?w=900&h=383" alt="" title=""></p>
<p>Fundebug的<a href="https://link.segmentfault.com/?enc=q%2FdZev9I%2Bu5C%2B6A9tn8qgA%3D%3D.QEklb%2BYxWL2rqyJLtVXoC9GV9gI04XSCGRDRI%2BG0F94%3D" rel="nofollow">付费套餐</a>主要是根据错误事件数制定的,这是因为每一个发送到我们服务器的事件,都会消耗一定的CPU、内存、磁盘以及带宽资源,尤其当错误事件数非常大时,会对我们的计算资源造成很大压力。</p>
<p>如果您希望采样收集错误,比如“只收集30%的错误”,可以将<strong>sampleRate</strong>属性设为0.3。这样的话,您可以选择更加合适套餐。</p>
<p><strong>1. 在HTML中配置<code><script></code>标签中配置sampleRate属性</strong></p>
<pre><code class="html"><script src="https://js.fundebug.cn/fundebug.1.9.0.min.js"
apikey="API-KEY"
sampleRate=0.3></script></code></pre>
<p><strong>2. 在JavaScript中配置sampleRate变量</strong></p>
<pre><code class="js">fundebug.sampleRate = 0.3;</code></pre>
<p>注意,是否收集错误是完全随机的,因此理论上这样可能会导致一些错误不会被收集。因此,您需要自行权衡利弊,选择是否配置sampleRate以及配置多大的sampleRate。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=2K%2B0jkem8RVB9Df%2BkNTyeA%3D%3D.BeRCp0f4w509xi8jH2di8pXdUIXeEfHBQGg3z96Z0NvqEuFVSadacxoFfXVS452CCDl6REuiyxcLvbQ67t36IvmCJH8Cb%2FlubfYe%2FV7FTyo%3D" rel="nofollow">Fundebug计费标准解释:事件数是如何定义的?</a></li></ul>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=0PLJ54YEkEHr32Vpi%2F0BmQ%3D%3D.qOEHWNdB81%2BHbgoOWA9UDFylbmyVGqfcH%2BH4IeH7y7M%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=T6S1B%2FMpWla97YwkCDpfXw%3D%3D.vXrNTa%2Bf2rygkthyH5gLvcOlsTOiP2cEBuaW3fVl7AfFJxVABqkb8R0BFpVAWynosLzja%2Ba1WMpCv302uBuUjQ%3D%3D" rel="nofollow">https://blog.fundebug.com/2018/05/09/fundebug-javascript-0-4-0/</a></p>
为什么重复的GET请求变慢了?
https://segmentfault.com/a/1190000019787042
2019-07-17T12:13:32+08:00
2019-07-17T12:13:32+08:00
Fundebug
https://segmentfault.com/u/fundebug
3
<p>最近在研究慢请求监控的问题,写了一个简单的测试代码:在网页端(<code>index.html</code>)通过<code>fetch</code>函数向服务端获取数据,然后打印请求耗时。</p>
<pre><code class="js">function requestData() {
let start = new Date();
fetch("http://localhost:3000/company/basic")
.then(res => {
return res.json();
})
.then(res => {
let span = new Date() - start;
console.log("span:", span);
});
}
requestData();</code></pre>
<p>在服务端通过<code>setTimeout</code>延时<code>1500s</code>才返回数据(服务端使用<a href="https://link.segmentfault.com/?enc=FtVZQSCA%2FV%2Felzcb2jZLDQ%3D%3D.2wf5sOsuv0NebAuk60WIkjBNhoTUJr%2BqOmt4dx5wrFk%3D" rel="nofollow">ExpressJS</a>)。</p>
<pre><code class="js">app.get("/company/basic", (req, res) => {
setTimeout(function() {
res.send({ hello: "Hello Fundebug!" });
}, 1500);
});</code></pre>
<p>不出所料,<code>span</code>数据都略微大于 1500。</p>
<p>而后,我突发奇想,假设我同时发送多个请求会怎么样呢?于是有了如下代码:</p>
<pre><code class="js">[1, 2, 3].forEach(function() {
requestData();
});</code></pre>
<p>结果好像也没问题,在 Chrome 浏览器下面是这个效果:</p>
<p><img src="/img/remote/1460000019787045" alt="" title=""></p>
<h3>接入 Fundebug 慢请求监控测试</h3>
<p>于是愉快地接入 Fundebug 监控:</p>
<pre><code class="html"><script
src="https://js.fundebug.cn/fundebug.1.9.0.min.js"
apikey="API-KEY"
></script></code></pre>
<p>并设置如果请求时长超过 2 秒就上报:</p>
<pre><code class="js">if ("fundebug" in window) {
fundebug.httpTimeout = 2000;
}</code></pre>
<p>本以为刷新页面,应该不会收到报错。</p>
<p>结果,万万没想到的是,Fundebug 收到 2 个慢请求报错。</p>
<p><img src="/img/remote/1460000019787046" alt="" title=""></p>
<p>这不科学啊!</p>
<p>点开错误详情,可以看到具体的报错信息。一个请求耗时 3018 毫秒,一个请求耗时 4525 毫秒。</p>
<p><img src="/img/remote/1460000019787047?w=1352&h=801" alt="" title=""></p>
<p>也就是说,第一个请求没问题,假设是 1500 毫秒。我们把三个请求的时间放一起看看有何规律:1500,3018,4524。他们近似成等差数列,相差 1500 毫秒。于是,我怀疑三个请求是一个一个阻塞式的,而不是并发的。</p>
<h3>测试并发请求不同 API 的情况</h3>
<p>为了验证这一点,我将测试改为请求三个不同的 API 接口。</p>
<p>服务端代码:</p>
<pre><code class="js">app.get("/company/basic", resp);
app.get("/company/basic1", resp);
app.get("/company/basic2", resp);
function resp(req, res) {
setTimeout(function() {
res.send({ hello: "Hello Fundebug!" });
}, 1500);
}</code></pre>
<p>网页端代码(<code>requestData</code>函数传入请求的 URL):</p>
<pre><code class="js">[
"http://localhost:3000/company/basic",
"http://localhost:3000/company/basic1",
"http://localhost:3000/company/basic2"
].forEach(function(item) {
requestData(item);
});</code></pre>
<p>为了获取请求数据,将<code>httpTimeout</code>改为 1500。</p>
<pre><code class="js">if ("fundebug" in window) {
fundebug.httpTimeout = 1500;
}</code></pre>
<p>Fundebug 捕获三个请求的时间,分别为 1526,1525,1529。</p>
<p><img src="/img/remote/1460000019787048?w=1354&h=274" alt="" title=""></p>
<p>至此大体验证了刚刚的假设:对同一个 API 接口的并发请求会被阻塞,对不同的 API 接口并发请求正常执行。</p>
<p>那么为什么会被阻塞呢?意图何在?接下来慢慢给各位介绍。</p>
<h3>背后的原因</h3>
<p>在<a href="https://link.segmentfault.com/?enc=UwtGyTbUDVtWsyOawxdSBQ%3D%3D.T0GiQBo0sn%2BXPM4Q330cEXp9bwiwg5TxPqYbcSYzT0xkfNtNs6rgQVQ0YQXR9rG63KKh8Js%2BFnKsQ%2B%2FIaNgxiHLmmFqvnxzqT6R3mcnX47LyiOEZ6RMYqlbFntUo1l2LNx0qK7abfmdtX89rihxPUg%3D%3D" rel="nofollow">StackOverflow</a>上找到了答案:</p>
<blockquote>Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique.</blockquote>
<p>也就是说,Chrome 特意做了这样的设计。对于连续的相同请求,Chrome 会阻塞后面的请求,直到前面的完成。通过判断前面的请求返回的 Header 里面的缓存设置来决定下一步的行动。</p>
<p>我们可以做个实验来验证一下。</p>
<h3>缓存实验</h3>
<ul>
<li>
<p>服务端设置缓存 2 秒</p>
<p>在服务端的接口返回代码中配置缓存时间</p>
<pre><code class="js">res.setHeader("Cache-Control", "public, max-age=2");</code></pre>
<p><img src="/img/remote/1460000019787049" alt="" title=""></p>
</li>
<li>
<p>服务端设置不缓存</p>
<pre><code class="js">res.setHeader(
"Cache-Control",
"private, no-cache, no-store, must-revalidate"
);</code></pre>
<p><img src="/img/remote/1460000019787050?w=2560&h=410" alt="" title=""></p>
</li>
<li>Chrome 开发者面板设置<code>Disable Cache</code><p><img src="/img/remote/1460000019787051?w=2560&h=400" alt="" title=""></p>
</li>
</ul>
<h3>最后的疑问</h3>
<p>为什么打开和不打开谷歌开发者控制台,行为会不一样了?</p>
<p>其实是有原因的,而且这个干扰项一度成功阻止了我发现问题的本质。当我们在开发前端项目的时候,代码的改动希望能够实时地反应到网页上,而不是受到浏览器缓存的影响,但是我们发现往往刷新页面的时候没有真的去服务端获取数据,还是老的信息。于是,我们会去配置一个选项,将<code>Disable Cache</code>设置为<code>true</code>。也就是说,在开发环境下,缓存是被禁用了的,也就不存在等待第一个请求返回然后判断其 Header 里面<code>Cache-Control</code>设置的问题。这也是为什么打开谷歌开发者控制台,请求没有等待,立即执行了。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=6fZxWw70LQo4aY7MY0qqNA%3D%3D.3SsBzl2%2F3tPmC2fQop9KA4uu0c4hm%2BZczKOep7yc7R8%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=tZ6y%2BuqiFm5meQz1CVQMIA%3D%3D.jiZq4VebuEjt7Zab971zDfqVQBBX3y8hck%2Be%2BCv883%2BA9gsBEXrU4VUHBKc%2BwiAs" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=yZQAIqzefO1A86fpg6lLzA%3D%3D.ukIDs9lKGdulNxJRcVcYUQug8Ak6AvyLxeRZPtFROY1KH%2BZnh8QI7gOKr%2F%2BBLBDieP48eu2tc71wJQPCz%2FtB99HAdJPGfSTHQJ%2FXcQ%2BGzJs%3D" rel="nofollow">https://blog.fundebug.com/2019/07/17/chrome-stall-multiple-same-request/</a></p>
JavaScript深入浅出第4课:V8引擎是如何工作的?
https://segmentfault.com/a/1190000019772177
2019-07-16T09:04:01+08:00
2019-07-16T09:04:01+08:00
Fundebug
https://segmentfault.com/u/fundebug
16
<p><strong>摘要:</strong> 性能彪悍的V8引擎。</p>
<p><strong>《<a href="https://link.segmentfault.com/?enc=Ul9GL1UR%2FWKIQOSDTt9f0Q%3D%3D.aBMGe6RyU%2F5hhizUNsue7PEVw54W50xaXn6%2Fuxnf16713mUEFGGQP6pyZk9RdQ%2BZDBVtpybJrY6DjkTMa6HiTSqDIvY97JMCfkhfXPyY8zI%3D" rel="nofollow">JavaScript深入浅出</a>》系列</strong>:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=tOusmss7ayQzk8zB5f%2FWRw%3D%3D.HMdNzdKV76rlWgDRCtqIHkKZPaum2Jlau8uM%2BWpjTgmNOxlsYa2Ia2CR4GhWL1wHA%2BLGsoPSs9u%2B3SOINryCMg%3D%3D" rel="nofollow">JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?</a></li>
<li><a href="https://link.segmentfault.com/?enc=LE2oskQ3LVozfBq6EhDmmA%3D%3D.N8L81h4o3UsRAXWQLYN35nZnsndsSolwpg%2F8Q3xKgIFEB6eEBBapvua7yQrYECDexFBtPZ%2F6j5%2BwAxzEHkAnQLxSt%2B5ApsV%2F5hO8E22gauU%3D" rel="nofollow">JavaScript深入浅出第2课:函数是一等公民是什么意思呢?</a></li>
<li><a href="https://link.segmentfault.com/?enc=nb40LsgCt2YUmNilrMw1TA%3D%3D.a%2B9Aoi%2Fdm9TNgKwK%2FWNO6eKHv55uHb6Az%2Fkj09vfDeWyGTZDFMoFtrLiEJbhzO3gK%2FNzbXml%2BKb1c2N2xc6X0NgSJ1DmVGMbTFJGKT7Cj%2BM%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a></li>
<li><a href="https://link.segmentfault.com/?enc=4i%2BRRvIwVArOGBeFkSmChg%3D%3D.QN8jvf2ybUwwDnxOcqBDtgOt%2BvwCZ%2F433PwIfk1jxSFwofYMxkPRFaSLdazbiuH%2FvjE0pst48JqNRESIOzJKcQ%3D%3D" rel="nofollow">JavaScript深入浅出第4课:V8是如何工作的?</a></li>
</ul>
<p>最近,JavaScript生态系统又多了2个非常硬核的项目。</p>
<p>大神<a href="https://link.segmentfault.com/?enc=g5CXb7oY3rn3TKmjWCeqag%3D%3D.nPeAGzOrJiRuFR8TkaXxfFnM5pCaxd36une%2BVjpJ0%2FxGS108v38fGwP1WnoIHkpU" rel="nofollow">Fabrice Bellard</a>发布了一个新的JS引擎<a href="https://link.segmentfault.com/?enc=pM9xeVjZ74WmGyGpcM00Zg%3D%3D.vAZNV%2Fb6yyeDuoS%2BBIcuh%2FHL23bYHsIPgjl14IMceFU%3D" rel="nofollow">QuickJS</a>,可以将JavaScript源码转换为C语言代码,然后再使用系统编译器(gcc或者clang)生成可执行文件。</p>
<p>Facebook为React Native开发了新的JS引擎<a href="https://link.segmentfault.com/?enc=z0dalw3srk7CRPVPpanqHA%3D%3D.UHcJy%2B7DWGLU5bXft95wiMrazAGfxXc3lOCwAt90AJY%3D" rel="nofollow">Hermes</a>,用于优化安卓端的性能。它可以在构建APP的时候将JavaScript源码编译为Bytecode,从而减少APK大小、减少内存使用,提高APP启动速度。</p>
<p>作为JavaScript程序员,只有极少数人有机会和能力去实现一个JS引擎,但是理解JS引擎还是很有必要的。本文将介绍一下V8引擎的原理,希望可以给大家一些帮助。</p>
<h3>JavaScript引擎</h3>
<p>我们写的JavaScript代码直接交给浏览器或者Node执行时,底层的CPU是不认识的,也没法执行。CPU只认识自己的指令集,指令集对应的是汇编代码。写汇编代码是一件很痛苦的事情,比如,我们要计算N阶乘的话,只需要7行的递归函数:</p>
<pre><code class="javascript">function factorial(N) {
if (N === 1) {
return 1;
} else {
return N * factorial(N - 1);
}
}</code></pre>
<p>代码逻辑也非常清晰,与阶乘的数学定义完美吻合,哪怕不会写代码的人也能看懂。</p>
<p>但是,如果使用汇编语言来写N阶乘的话,要300+行代码<a href="https://link.segmentfault.com/?enc=1mue7qSDB%2F6WDbQ%2Bhsf%2Fgw%3D%3D.4S3FMNIM%2F98PvpnLeVxCkZGX4rTf9FYUWzWbUrpe7wl%2Fl5mR1ao0tKoEylAgaM%2B%2B%2BOtP%2BDHIah0A%2FRX7bbzCBJstoWvLBsBFUfgaPsXjeeEfcQytOHscdXDeSsdSMgxOX6929rGMwtRYJVkwsvqw9w%3D%3D" rel="nofollow">n-factorial.s</a>:</p>
<p><img src="/img/remote/1460000019772184?w=454&h=441" alt="" title=""></p>
<p>这个N阶乘的汇编代码是我大学时期写的,已经是N年前的事情了,它需要处理10进制与2进制的转换,需要使用多个字节保存大整数,最多可以计算大概500左右的N阶乘。</p>
<p>还有一点,不同类型的CPU的指令集是不一样的,那就意味着得给每一种CPU重写汇编代码,这就很崩溃了。。。</p>
<p>还好,<strong>JavaScirpt引擎可以将JS代码编译为不同CPU(Intel, ARM以及MIPS等)对应的汇编代码</strong>,这样我们才不要去翻阅每个CPU的指令集手册。当然,JavaScript引擎的工作也不只是编译代码,它还要负责执行代码、分配内存以及<a href="https://link.segmentfault.com/?enc=ggRqKt1Fv9IIL4uZdgIKDA%3D%3D.MS23KEI9kTPpAAtpezsTsAdK0DTMyEeP82csNEFHo8eOx3BSdG2phMGodZIa1lnViz0m8p3u%2B4YB54KWnqbMSDxcCdYLLPQS3p6ndWA7MAQ%3D" rel="nofollow">垃圾回收</a>。</p>
<p>虽然浏览器非常多,但是主流的JavaScirpt引擎其实很少,毕竟开发一个JavaScript引擎是一件非常复杂的事情。比较出名的JS引擎有这些:</p>
<ul>
<li>
<a href="https://link.segmentfault.com/?enc=ZpcMXIiysPY%2FMtvuMOIKOw%3D%3D.VrUEe1UQdZ4dep%2Fe1%2BMopA%3D%3D" rel="nofollow">V8</a> (Google)</li>
<li>
<a href="https://link.segmentfault.com/?enc=VA52P6oEmfJoFCOt3pUXDw%3D%3D.Yk%2FOitp%2BX%2BsSmpqBGfk7my5Z1l02rcgGGo5rkBSvYtqlbiVWuH8vzTRYqSvuAM6UMSDPR3YItyEdDm60DinkN1My1AwMFtaJK7nKzeOnqp8%3D" rel="nofollow">SpiderMonkey</a> (Mozilla)</li>
<li>
<a href="https://link.segmentfault.com/?enc=sFlVLsyUp6c8jV%2BWgEiJOw%3D%3D.kWsVvwCB%2BWFD4bgNOvzqAOVK2KbXqQ7XCA47hSa7Rw2GX1xqiQWpPbWybQ%2FcaPzuQU7B75vt4QdRB8PYsold6vjtME%2Bw5ltCxI5toJp26sE%3D" rel="nofollow">JavaScriptCore</a> (Apple)</li>
<li>
<a href="https://link.segmentfault.com/?enc=mQlOS%2BK6KQuBqyQPLOkfPA%3D%3D.qnQhJU1n0HGVmvp5oYq5AsBEdwWjXkMBiNjUvyo9RQuSFNya8epEeLwgK3sDdfp6" rel="nofollow">Chakra</a> (Microsoft)</li>
<li>IOT:<a href="https://link.segmentfault.com/?enc=QAuYvK%2F18X1l0sEmetJoPQ%3D%3D.bFxn6LHtNzLYvUVw8xjuBKMkTAimgJOsniBK%2FNIVEzLO%2F43VXEm%2FB%2FTHIUP3oyNC" rel="nofollow">duktape</a>、<a href="https://link.segmentfault.com/?enc=9NqKsGZxYeKhZOdGxrI7IQ%3D%3D.jkGCGtws1FgNbpY8Qyfc35cJEyvBeTaf2EfoUJOr6uFMtwr8dofIy5JTNMFOqwtkwka%2BlxFjWuISTG3eppX2QQ%3D%3D" rel="nofollow">JerryScript</a>
</li>
</ul>
<p>还有,最近发布<a href="https://link.segmentfault.com/?enc=5e846Xi0fe0Scc3mene3HA%3D%3D.MBq8NKcsJPnqhIdfiL8J4b9ONwZIvLtlonXAZjH4Mx4%3D" rel="nofollow">QuickJS</a>与<a href="https://link.segmentfault.com/?enc=g316FxQVhrBM5ECns%2FoNdQ%3D%3D.Q0OJLLVNYUtlwHRhPw3md5Ly5UiKJ7Z30h4ERO4AbB8%3D" rel="nofollow">Hermes</a>也是JS引擎,它们都超越了浏览器范畴,<a href="https://link.segmentfault.com/?enc=bRWpt7%2BLy693uzwVSwspNQ%3D%3D.f09QKd9B1WuLM%2BGDn%2FuPLz4UID9eF4tO0RbjlgcOi389i4g%2BSVi2mxUi9VOreeQDvS8Vrvx0Si3I9fcledUvcA%3D%3D" rel="nofollow">Atwood's Law</a>再次得到了证明:</p>
<blockquote>Any application that can be written in JavaScript, will eventually be written in JavaScript.</blockquote>
<h3>V8:强大的JavaScript引擎</h3>
<p>在为数不多JavaScript引擎中,V8无疑是最流行的,Chrome与Node.js都使用了V8引擎,Chrome的市场占有率高达60%,而Node.js是JS后端编程的事实标准。国内的众多浏览器,其实都是基于Chromium浏览器开发,而Chromium相当于开源版本的Chrome,自然也是基于V8引擎的。神奇的是,就连浏览器界的独树一帜的Microsoft也投靠了Chromium阵营。另外,Electron是基于Node.js与Chromium开发桌面应用,也是基于V8的。</p>
<p>V8引擎是2008年发布的,它的命名灵感来自超级性能车的V8引擎,敢于这样命名确实需要一些实力,它性能确实一直在稳步提高,下面是使用<a href="https://link.segmentfault.com/?enc=htNouPIgFc40704S8afgtA%3D%3D.fSp%2B1yGUrfJIX4IrPHIFirDVqaP%2B2TrP%2BiWVz%2BjtwETDzpnUt9XF6u97pS%2BHBNiz" rel="nofollow">Speedometer benchmark</a>的测试结果:</p>
<p><img src="/img/remote/1460000019772185?w=1247&h=572" alt="" title=""><br><em>图片来源:<a href="https://link.segmentfault.com/?enc=LZVT3rO1qbT%2BILXiOmuTGA%3D%3D.Wd7AhStLDPfEdEZucTv8Vg%3D%3D" rel="nofollow">https://v8.dev/</a></em></p>
<p>V8在工业界已经非常成功了,同时它还获得了学术界的肯定,拿到了ACM SIGPLAN的<a href="https://link.segmentfault.com/?enc=XqLBx4k9gpO%2FE5wkSZy0Lw%3D%3D.gFZZxrrY1m9nXOW95qpkM%2BSPRTWdz2iQ3Rf1c47iqfD1JoifAmy5Qnejo%2FzLvlWj" rel="nofollow">Programming Languages Software Award</a>:</p>
<blockquote>V8's success is in large part due to the efficient machine code it generates.<br>Because JavaScript is a highly dynamic object-oriented language, many experts believed that this level of performance could not be achieved. <br>V8's performance breakthrough has had a major impact on the adoption of JavaScript, which is nowadays used on the browser, the server, and probably tomorrow on the small devices of the internet-of-things.</blockquote>
<p>JavaScript是一门动态类型语言,这会给编译器增加很大难度,因此专家们觉得它的性能很难提高,但是V8居然做到了,生成了非常高效的machine code(其实是汇编代码),这使得JS可以应用在各个领域,比如Web、APP、桌面端、服务端以及IOT。</p>
<p>严格来讲,V8所生成的代码是汇编代码而非机器代码,但是V8相关的文档、博客以及其他资料都把V8生成的代码称作machine code。汇编代码与机器代码很多是一一对应的,也很容易互相转换,这也是反编译的原理,因此他们把V8生成的代码称为Machine Code也未尝不可,但是并不严谨。</p>
<h3>V8引擎的内部结构</h3>
<p><a href="https://link.segmentfault.com/?enc=oKEGYBOWLB6hbTXFppVpwQ%3D%3D.HRJXPPn%2FTvCjmnwPQoWO80T8rECk5%2Bu3xBYKhCbQeOg%3D" rel="nofollow">V8</a>是一个非常复杂的项目,使用<a href="https://link.segmentfault.com/?enc=tKTjW98NFAGakw3%2FxuYJNQ%3D%3D.TNdFNfX%2BzqsfX58swAMXaB7BuP0yopbDu4WK%2Br9zp1BJej91SAVcBcyyNCOEK%2FF3" rel="nofollow">cloc</a>统计可知,它竟然有<strong>超过100万行C++代码</strong>。</p>
<p>V8由许多子模块构成,其中这4个模块是最重要的:</p>
<ul>
<li>
<a href="https://link.segmentfault.com/?enc=lmCaIvU7wg9%2FjB4heorEYA%3D%3D.6%2BFJEAdaFcE%2BU50hkItYdzgjCw%2FSFkgmm%2Fdv9dF%2B44c%3D" rel="nofollow">Parser</a>:负责将JavaScript源码转换为Abstract Syntax Tree (AST)</li>
<li>
<a href="https://link.segmentfault.com/?enc=vRthcFW0GEPp9Bzi3xTOVQ%3D%3D.l%2BHFyXsejDwzsftQpyWcZgky6SFwolBUA%2FjxgIQ9a8M%3D" rel="nofollow">Ignition</a>:interpreter,即解释器,负责将AST转换为Bytecode,解释执行Bytecode;同时收集TurboFan优化编译所需的信息,比如函数参数的类型;</li>
<li>
<a href="https://link.segmentfault.com/?enc=MSlvYOCblCEYCBQX0nv4vA%3D%3D.JihTF9doTFJOBJnP3C5TbU2Y6vrxq2iLeRpbBMUgXyA%3D" rel="nofollow">TurboFan</a>:compiler,即编译器,利用Ignitio所收集的类型信息,将Bytecode转换为优化的汇编代码;</li>
<li>
<a href="https://link.segmentfault.com/?enc=%2BrCttelb4bSN0qxsSo%2BVGw%3D%3D.rFCCgnGUmGYlz7P7f%2BdAK%2BaMwxEbHqiLv%2Bf%2B2b4C1K4%3D" rel="nofollow">Orinoco</a>:garbage collector,<a href="https://link.segmentfault.com/?enc=YQHFz4N4ID%2FLFMBtQ409lw%3D%3D.80mc67vVcTwCGsYW8wjfUa2qwK%2BGEvQRsm4NUu3bW%2B6MdbecOv5o0wuikfyzzBFs66xzfdQXmjCY4xSRjVoF6dsrIviLbLXtTwu9YZsr8OU%3D" rel="nofollow">垃圾回收</a>模块,负责将程序不再需要的内存空间回收;</li>
</ul>
<p>其中,Parser,Ignition以及TurboFan可以将JS源码编译为汇编代码,其流程图如下:</p>
<p><img src="/img/remote/1460000019774163?w=700&h=524" alt="" title=""></p>
<p>简单地说,Parser将JS源码转换为AST,然后Ignition将AST转换为Bytecode,最后TurboFan将Bytecode转换为经过优化的Machine Code(实际上是汇编代码)。</p>
<ul>
<li>如果函数没有被调用,则V8不会去编译它。</li>
<li>如果函数只被调用1次,则Ignition将其编译Bytecode就直接解释执行了。TurboFan不会进行优化编译,因为它需要Ignition收集函数执行时的类型信息。这就要求函数至少需要执行1次,TurboFan才有可能进行优化编译。</li>
<li>如果函数被调用多次,则它有可能会被识别为热点函数,且Ignition收集的类型信息证明可以进行优化编译的话,这时TurboFan则会将Bytecode编译为Optimized Machine Code,以提高代码的执行性能。</li>
</ul>
<p>图片中的红线是逆向的,这的确有点奇怪,Optimized Machine Code会被还原为Bytecode,这个过程叫做Deoptimization。这是因为Ignition收集的信息可能是错误的,比如add函数的参数之前是整数,后来又变成了字符串。生成的Optimized Machine Code已经假定add函数的参数是整数,那当然是错误的,于是需要进行Deoptimization。</p>
<pre><code class="javascript">function add(x, y) {
return x + y;
}
add(1, 2);
add("1", "2");</code></pre>
<p>在运行C、C++以及Java等程序之前,需要进行编译,不能直接执行源码;但对于JavaScript来说,我们可以直接执行源码(比如:node server.js),它是在运行的时候先编译再执行,这种方式被称为即时编译(Just-in-time compilation),简称为JIT。因此,V8也属于JIT编译器。</p>
<h3>Ignition:解释器</h3>
<p><img src="/img/remote/1460000019772187?w=316&h=375" alt="" title=""></p>
<p>Node.js是基于V8引擎实现的,因此node命令提供了很多V8引擎的选项,使用node的<code>--print-bytecode</code>选项,可以打印出Ignition生成的Bytecode。</p>
<p>factorial.js如下,由于V8不会编译没有被调用的函数,因此需要在最后一行调用factorial函数。</p>
<pre><code class="javascript">function factorial(N) {
if (N === 1) {
return 1;
} else {
return N * factorial(N - 1);
}
}
factorial(10); // V8不会编译没有被调用的函数,因此这一行不能省略</code></pre>
<p>使用node命令(node版本为12.6.0)的<code>--print-bytecode</code>选项,打印出Ignition生成的Bytecode:</p>
<pre><code class="bash">node --print-bytecode factorial.js</code></pre>
<p>控制台输出的内容非常多,最后一部分是factorial函数的Bytecode:</p>
<pre><code class="javascript">[generated bytecode for function: factorial]
Parameter count 2
Register count 3
Frame size 24
18 E> 0x3541c2da112e @ 0 : a5 StackCheck
28 S> 0x3541c2da112f @ 1 : 0c 01 LdaSmi [1]
34 E> 0x3541c2da1131 @ 3 : 68 02 00 TestEqualStrict a0, [0]
0x3541c2da1134 @ 6 : 99 05 JumpIfFalse [5] (0x3541c2da1139 @ 11)
51 S> 0x3541c2da1136 @ 8 : 0c 01 LdaSmi [1]
60 S> 0x3541c2da1138 @ 10 : a9 Return
82 S> 0x3541c2da1139 @ 11 : 1b 04 LdaImmutableCurrentContextSlot [4]
0x3541c2da113b @ 13 : 26 fa Star r1
0x3541c2da113d @ 15 : 25 02 Ldar a0
105 E> 0x3541c2da113f @ 17 : 41 01 02 SubSmi [1], [2]
0x3541c2da1142 @ 20 : 26 f9 Star r2
93 E> 0x3541c2da1144 @ 22 : 5d fa f9 03 CallUndefinedReceiver1 r1, r2, [3]
91 E> 0x3541c2da1148 @ 26 : 36 02 01 Mul a0, [1]
110 S> 0x3541c2da114b @ 29 : a9 Return
Constant pool (size = 0)
Handler Table (size = 0)</code></pre>
<p>生成的Bytecode其实挺简单的:</p>
<ul>
<li>使用LdaSmi命令将整数1保存到寄存器;</li>
<li>使用TestEqualStrict命令比较参数a0与1的大小;</li>
<li>如果a0与1相等,则JumpIfFalse命令不会跳转,继续执行下一行代码;</li>
<li>如果a0与1不相等,则JumpIfFalse命令会跳转到内存地址0x3541c2da1139</li>
<li>...</li>
</ul>
<p>不难发现,Bytecode某种程度上就是汇编语言,只是它没有对应特定的CPU,或者说它对应的是虚拟的CPU。这样的话,生成Bytecode时简单很多,无需为不同的CPU生产不同的代码。要知道,V8支持9种不同的CPU,引入一个中间层Bytecode,可以简化V8的编译流程,提高可扩展性。</p>
<p>如果我们在不同硬件上去生成Bytecode,会发现生成代码的指令是一样的:</p>
<p><img src="/img/remote/1460000019772188?w=960&h=540" alt="" title=""><br><em>图片来源:<a href="https://link.segmentfault.com/?enc=loLnhQDWG%2F5kNliLMq0RIw%3D%3D.ZNCUUaJQk7Gs5YJPeBVApipDlJl%2Brm82J%2BM0aZD2SjVnhcHLG0%2F8IdlgdZQ19xpG" rel="nofollow">Ross McIlroy</a></em></p>
<h3>TurboFan:编译器</h3>
<p><img src="/img/remote/1460000019772189?w=375&h=313" alt="" title=""></p>
<p>使用node命令的<code>--print-code</code>以及<code>--print-opt-code</code>选项,打印出TurboFan生成的汇编代码:</p>
<pre><code class="bash">node --print-code --print-opt-code factorial.js</code></pre>
<p>我是在Mac上运行的,结果如下图所示:</p>
<p><img src="/img/remote/1460000019772190?w=576&h=216" alt="" title=""></p>
<p>比起Bytecode,正真的汇编代码可读性差很多。而且,机器的CPU类型不一样的话,生成的汇编代码也不一样。</p>
<p>这些汇编代码就不用去管它了,因为最重要的是理解TurboFan是如何优化所生成的汇编代码的。我们可以通过add函数来梳理整个优化过程。</p>
<pre><code class="javascript">function add(x, y) {
return x + y;
}
add(1, 2);
add(3, 4);
add(5, 6);
add("7", "8");</code></pre>
<p>由于JS的变量是没有类型的,所以add函数的参数可以是任意类型:Number、String、Boolean等,这就意味着add函数可能是数字相加(V8还会区分整数和浮点数),可能是字符串拼接,也可能是其他更复杂的操作。如果直接编译的话,生成的代码比如会有很多if...else分支,伪代码如下:</p>
<pre><code class="javascript">if (isInteger(x) && isInteger(y)) {
// 整数相加
} else if (isFloat(x) && isFloat(y)) {
// 浮点数相加
} else if (isString(x) && isString(y)) {
// 字符串拼接
} else {
// 各种其他情况
}</code></pre>
<p>我只写了4个分支,实际上的分支其实更多,比如当参数类型不一致时还得进行类型转换,大家不妨看看ECMASCript对加法是如何定义的:<a href="https://link.segmentfault.com/?enc=6ZK2kel24ydzN5mKwHE0jQ%3D%3D.ZKnBJQOIPgUASXZUBqhYL23uF0w0lBS%2FATj1YVNjv60e5m2vcVKqpDlLN0mzZVdMSu%2F2aVNJfsPgFkIJmpdG1A%3D%3D" rel="nofollow">12.8.3The Addition Operator ( + )</a>。</p>
<p>如果直接按照伪代码去生成汇编代码,那生成的代码必然非常冗长,这样会占用很多内存空间。</p>
<p>Ignition在执行<code>add(1, 2)</code>时,已经知道add函数的两个参数都是整数,那么TurboFan在编译Bytecode时,就可以假定add函数的参数是整数,这样可以极大地简化生成的汇编代码,伪代码如下:</p>
<pre><code class="javascript">if (isInteger(x) && isInteger(y)) {
// 整数相加
} else {
// Deoptimization
}</code></pre>
<p>当然这样做也是有风险的,因为如果add函数参数不是整数,那么生成的汇编代码也没法执行,只能Deoptimize为Bytecode来执行。</p>
<p>也就是说,如果TurboFan对add函数进行编译优化的话,则<code>add(3, 4)</code>与<code>add(3, 4)</code>可以执行优化的汇编代码,但是<code>add("7", "8")</code>只能Deoptimize为Bytecode来执行。</p>
<p>当然,TurboFan所做的也不只是根据类型信息来简化代码执行流程,它还会进行其他优化,比如减少冗余代码等更复杂的事情。</p>
<p>由这个简单的例子可知,如果我们的JS代码中变量的类型变来变去,是会给V8引擎增加不少麻烦的,为了提高性能,我们可以尽量不要去改变变量的类型。</p>
<p>对于性能要求比较高的项目,使用TypeScript也是不错的选择,理论上,如果严格遵守类型化的编程方式,也是可以提高性能的,类型化的代码有利于V8引擎优化编译的汇编代码,当然这一点还需要测试数据来证明。</p>
<h3>Orinoco:垃圾回收</h3>
<p><img src="/img/remote/1460000019772191?w=260&h=320" alt="" title=""></p>
<p>强大的垃圾回收功能是V8实现提高性能的关键之一,因为它可以在避免影响JS代码执行的情况下,同时回收内存空间,提高内存利用效率。</p>
<p>关于垃圾回收,我在<a href="https://link.segmentfault.com/?enc=p5EnzMnVW1syv4brXmOXEw%3D%3D.puVVGOGb2WV4oc5w45m0DX2WTRbpcBYcc8ZD5fz8jAmL8qYKpLzGhcBOAKYsf46zkiW6t3MO0ek5ER4sny9ddR7txAmuWJf96bkcldlyIKU%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a>中有详细介绍,这里就不再赘述了。</p>
<h3>JS引擎的未来</h3>
<p>V8引擎确实很强大,但是它也不是无所不能的,简单地分析都可以发现一些可以优化的点。</p>
<p>我有一个新的想法,还没想好名字,不妨称作Optimized TypeScript Engine:</p>
<ul>
<li>使用TypeScript编程,遵循严格的类型化编程规则,不要写成AnyScript了;</li>
<li>构建的时候将TypeScript直接编译为Bytecode,而不是生成JS文件,这样运行的时候就省去了Parse以及生成Bytecode的过程;</li>
<li>运行的时候,需要先将Bytecode编译为对应CPU的汇编代码;</li>
<li>由于采用了类型化的编程方式,有利于编译器优化所生成的汇编代码,省去了很多额外的操作;</li>
</ul>
<p>这个想法其实可以基于V8引擎来实现,技术上应该是可行的:</p>
<ul>
<li>将Parser以及Ignition拆分出来,用于构建阶段;</li>
<li>删掉TurboFan处理JS动态特性的相关代码;</li>
</ul>
<p>这样做,可以将JS引擎简化很多,一方面不再需要parse以及生成bytecode,另一方面编译器不再需要因为JavaScript动态特性做很多额外的工作。因此可以减少CPU、内存以及电量的使用,优化性能,唯一的问题可能是必须使用严格的TS语法进行编程。</p>
<p>为啥要这样做呢?因为对于IOT硬件来说,CPU、内存、电量都是需要省着点用的,不是每一个智能家电都需要装一个骁龙855,如果希望把JS应用到IOT领域,必然需要从JS引擎角度去进行优化,只是去做上层的框架是没有用的。</p>
<p>其实,Facebook的<a href="https://link.segmentfault.com/?enc=e4vKZyc6iRSJWfmn4nj%2Bcg%3D%3D.ZYHELLRwG5S7OHEdP3gD3FoFCHQ9eXylZ98%2Fl7S6fWs%3D" rel="nofollow">Hermes</a>差不多就是这么干的,只是它没有要求用TS编程。</p>
<p>这应该是JS引擎的未来,大家会看到越来越多这样的趋势。</p>
<p>关于JS,我打算花1年时间写一个系列的博客<strong>《<a href="https://link.segmentfault.com/?enc=cNfNc%2BpkcwPGr3wpsEoakQ%3D%3D.AVXyXJYgCk8W2gZPx7UlAGseXpAOk8qFotchp57QJh8n1qj4hy7hN9lFly5faudgGGMsJX%2BNsuNm8hKwZTVzHm0HplO9yNg0T5B4RDMuK5A%3D" rel="nofollow">JavaScript深入浅出</a>》</strong>,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。欢迎添加我的个人微信(KiwenLau),我是<a href="https://link.segmentfault.com/?enc=c3AEk3sU5nd4pxm2rLD0iQ%3D%3D.3hK%2B%2BofAabMcJvjQAyiH1RX%2FoDB%2FgyQzgHBNZKQZmNQ%3D" rel="nofollow">Fundebug</a>的技术负责人,一个对JS又爱又恨的程序员。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=%2Fv%2FWjL%2FEKNzP1wOge8AjrA%3D%3D.29bVJSZiDjtwHXS%2BdZIyEEhu4o7ldnB6WyCizx7TqDU%3D" rel="nofollow">Celebrating 10 years of V8</a></li>
<li><a href="https://link.segmentfault.com/?enc=OLHb8PC%2Fh%2FcCSxCkDcBVPw%3D%3D.CKuctiNVW8OXXJ%2Bk6xWbHgJV7FkKB8d2zqcGBtZdkxdp7uM7MKYQNJVWIisKhuiBJFY3as3w9ttyQvucc1apVA%3D%3D" rel="nofollow">Launching Ignition and TurboFan</a></li>
<li><a href="https://link.segmentfault.com/?enc=q3KuhsjA9%2BF2%2FDMnKAaOtA%3D%3D.l5xUJp65BleU%2B73NoU1QsMCJR%2FXS0EOI0ID7gzZBPyU6GYK%2BBdgGqjhsixZR%2F73w" rel="nofollow">JavaScript engines - how do they even?</a></li>
<li><a href="https://link.segmentfault.com/?enc=emg7HFMcSsJBZXLiP%2FD2fA%3D%3D.PEgTzSoRHSHjMhC75XKZFjnrwXA2IX9o9c9c3298oUKCZZ7V%2FLrDwRWx8opQZz80lqz0jDB76na3JdOO67JH05HAh43s0kt7aldZsPqbYIJX9JzP%2FA08LvrJf3iErj2g" rel="nofollow">An Introduction to Speculative Optimization in V8</a></li>
<li><a href="https://link.segmentfault.com/?enc=xVgsLAUlnIx%2B7YSJhVK4Cw%3D%3D.SzQmEzGQIUhGBZcMC4%2BzmlgC2EHfiFUwd1eCQ9TjU3E4%2BXSY%2FGrYIJcXEJoS7K3%2FnAU4FjofdjitqRpTqxeukSfyInnfcdVVbZ78lTX0nKY%3D" rel="nofollow">Understanding V8’s Bytecode</a></li>
<li><a href="https://link.segmentfault.com/?enc=1ybY7Va2Vm%2F9DNUQjv4sKw%3D%3D.%2FJFSm4LcH%2BCkTQMMjEkBje%2FS8GYJfrbPAG37RdiBybsofW9S2faZLNL7lcf1zMx4MUdU51UNTjVUxNrbHbPUf8ts0YvPSTCPRyAO70v%2FCfU%3D" rel="nofollow">2018年,JavaScript都经历了什么?</a></li>
<li><a href="https://link.segmentfault.com/?enc=m61XNGg8X0ILfeI5%2F7oKuw%3D%3D.KLITt4Uehdwj4lpXdmFllGISDlgrSX%2FQ36tiXSr5l6frV4pq2Y52XGIUJq6JIFf6nUpSahs%2FbzpvzWmJO7GU%2FwsocRYmxIegk1U17Yhzr0M%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2Bs8Knj8hRIgb7gF%2FprqLYQ%3D%3D.7%2Bf8X2TISUEqOZCkUnkUoLmp3aF97%2F7pyDZz1yPA5VJH86dBy8dwifly%2BfAD%2BCSEAcUTbv%2BinXA%2Fq7q%2FXv%2F%2FRg%3D%3D" rel="nofollow">Fabrice Bellard 是个什么水平的程序员?</a></li>
<li><a href="https://link.segmentfault.com/?enc=09PAJB8lyj8JFYOGUv70cg%3D%3D.1TVvt3E4AhEn8HRJsXxVGtjtI688obluaGVaDwHJE7zqvh5vh%2F%2FEVPUeDJWx46gsn7LvqhM1lPVE0FKrtg6hhQ%3D%3D" rel="nofollow">如何评价 Fabrice Bellard 发布 QuickJS JS 引擎?</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=dLFaHy3jAPQcgWo8pOmahg%3D%3D.GNqF6Uf2e3IFsOoOSDCXBUOv%2FQRBWRl9H5cFRQ12P88%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!</p>
<p><a href="https://link.segmentfault.com/?enc=L%2FTFnTmJS5afnAtM9iQ1DQ%3D%3D.xCOIqWJWzq4LUubCHFGrFDK1zTHnwoirfh7mm20%2FgRQt7Cb2qneKmNr8MwR6T%2Fey" rel="nofollow"><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=3go5F1rTKHhgkpEkCVpcEw%3D%3D.5jj%2BqPy4k2YdA6Lj9h45WLUNrpKRVmmmchKfVBE3GFjjKSjBoQO59iggD4ZHPm7XK9P75WO3Tn2fJNfw0dxq%2FA%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/07/16/how-does-v8-work/</a></p>
99%的程序都没有考虑的网络异常?使用Fundebug.notify()主动上报
https://segmentfault.com/a/1190000019693336
2019-07-08T10:20:56+08:00
2019-07-08T10:20:56+08:00
Fundebug
https://segmentfault.com/u/fundebug
12
<p>近日看到一篇文章<a href="https://link.segmentfault.com/?enc=Tf4IzKKWbD3nNG8Zhrwvow%3D%3D.gZi1V%2F7zd%2Fu3d3PaYzsyjIg6fOnh88BUCqD0EDVdmZLc8%2BG5x%2FKjdAUApF2zJvJsw8L8y2OFpJQJPzkjZrjiAQ%3D%3D" rel="nofollow">99%的程序都没有考虑的网络异常</a>,开篇提到:</p>
<blockquote>绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中。如果没有做好异常的兼容和兜底处理,会极大的影响用户体验,严重的还会带来安全和资损风险。</blockquote>
<p>于是,笔者分析了 GitHub 上的一些开源微信小程序,发现大多数的代码异常处理确实是不够的。</p>
<ul><li>登录接口只考虑成功的情况,没考虑失败的情况</li></ul>
<pre><code class="js">//调用登录接口
wx.login({
success: function() {
wx.getUserInfo({
success: function(res) {
that.globalData.userInfo = res.userInfo;
typeof cb == "function" && cb(that.globalData.userInfo);
}
});
}
});</code></pre>
<ul>
<li>
<p>网络请求只考虑<code>then</code>不考虑<code>catch</code></p>
<pre><code class="js">util.getData(index_api).then(function(data) {
//this.setData({
//
//});
console.log(data);
});</code></pre>
</li>
<li>
<p>考虑了异常情况但是没有做妥善的处理</p>
<pre><code class="js">db.collection("config")
.where({})
.get()
.then(res => {
console.log(res);
if (res.data.length > 0) {
Taro.setStorage({
key: "config_gitter",
data: res.data[0]
});
}
})
.catch(err => {
console.error(err);
});</code></pre>
</li>
</ul>
<p>也许 99%的情况下接口都是正常返回的,只有 1%的情况会失败。看起来好像不是一件严重的事情,但是考虑到用户的量级,这个事情就不那么简单了。假设有 100 万用户,那么就有 1 万用户遇到异常情况,而且如果用户的使用频次很高,影响的何止 1 万用户。并且,如今产品都是体验至上,如果遇到这样的问题,用户极大可能就弃你而去,流失了客户就等于流失了收入。</p>
<p>如何妥善地处理接口异常的情况是一件严肃的事情,应当被重视起来。</p>
<h3>妥善处理请求异常</h3>
<p>那么,应当如何做呢?首先要定义请求异常的处理代码,比如微信开放接口的参数中有<code>fail</code>(“接口调用失败的回调函数”)、Promise 的<code>catch</code>部分;其次,根据异常可能导致的后果,在函数中做相应的处理。如果会导致后续操作失败、或则界面无反馈,那么应当在 fail 回调中正确处理;如果你真的认为基本不可能出问题,那么至少写个异常上报。即使出错了,也知道具体的情况。</p>
<p>下图是<a href="https://link.segmentfault.com/?enc=ccOSXIfLC9hWrxFmkr%2FgMQ%3D%3D.s5liTy9ZoJZzCPknl6tmPqD76KO1XWFrrF3AHt0IrzeR1JuhA5M7tTgydGGcE2403BEAGesD8vgxIm0SI6ntwuu7JEXbhI%2BBZUG6oVwdiYhWWOwN4S3JkcbYfc%2F1Z63I" rel="nofollow">微信支付接口</a>的参数列表,其中包含了接口调用失败的回调函数(<code>fail</code>)。</p>
<p><img src="/img/remote/1460000019693339?w=1007&h=766" alt="image-20190703114115173" title="image-20190703114115173"></p>
<p>而且官方也给出了示例:</p>
<pre><code class="js">wx.requestPayment({
timeStamp: "",
nonceStr: "",
package: "",
signType: "MD5",
paySign: "",
success(res) {},
fail(res) {}
});</code></pre>
<h3>在回调函数<code>fail</code>中上报异常</h3>
<p>为了确保完全掌握小程序的运行状况,我们将异常上报。Fundebug 的<a href="https://link.segmentfault.com/?enc=hKWmRvsNhW1hV0ATt6dpCg%3D%3D.%2FwSwpSdNUl5UpidjydtO2fA3rtnL7DaOH%2FvVnjprxYfDSqv5NHZu%2BNeDabKmrRtM" rel="nofollow">微信小程序插件</a>除了可以自动捕获异常外,还支持通过<a href="https://link.segmentfault.com/?enc=xZwIrIlMiHOGlUryWomaYg%3D%3D.0PAq9jLhDb253n57TmlIN4eIjBpkcmcsL5tawBtqYZ8v4TFpwisC1MlHxGTdnGiIGCUomvSaMrFlEwB7wuJtHg%3D%3D" rel="nofollow">API 接口</a>主动上报异常。</p>
<p>根据其官方文档:</p>
<blockquote>
<p>使用 fundebug.notify(),可以将自定义的错误信息发送到 Fundebug</p>
<p><strong>name</strong>: 错误名称,参数类型为字符串</p>
<p><strong>message</strong>: 错误信息,参数类型为字符串</p>
<p><strong>option</strong>: 可选对象,参数类型为对象,用于发送一些额外信息</p>
<p>示例:</p>
<pre><code class="js">fundebug.notify("Test", "Hello, Fundebug!", {
metaData: {
company: "云麒",
location: "厦门"
}
});</code></pre>
</blockquote>
<p>首先在 Fundebug 创建一个小程序监控项目,并按照指示接入插件,然后在<code>app.js</code>的<code>onLaunch</code>函数下面调用<code>wx.requestPayment</code>来进行测试。</p>
<p><img src="/img/remote/1460000019693340" alt="" title=""></p>
<p>Fundebug 的微信小程序插件捕获并上报了异常:</p>
<p><img src="/img/remote/1460000019693341?w=1288&h=423" alt="" title=""></p>
<p>在<code>metaData</code>标签还可以看到我们配置的 metaData,也就是<code>fail</code>回调函数的<code>res</code>参数。</p>
<p><img src="/img/remote/1460000019693342?w=1043&h=440" alt="" title=""></p>
<p>因此,我们可以知道失败的原因是订单过期。</p>
<p>另外,如果在二维码页面停留时间过久,也会触发报错:</p>
<p><img src="/img/remote/1460000019693343" alt="" title=""></p>
<p>通过简单的加入几行代码,就可以将小程序的异常情况了如指掌。而且 Fundebug 的微信小程序插件还可以监控线上 JavaScript 执行异常、自动捕获<code>wx.request</code>请求错误、监控慢 HTTP 请求,推荐大家接入试用!</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=Ihpxt9BlhitPrUCmTu4udA%3D%3D.CdSEK7%2BdoyVmGPl95VechJ4OfuX8QPIlOpitGdy0HdM%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=snpfJe01bR%2BKaVIW%2Fym5JQ%3D%3D.czq1zg2b4aQkWJEjINIXa397PkPIOs6Vj%2F2k3%2FdV8cG5NQ2UzXKYE%2BJnaKLEmHzI" rel="nofollow">免费试用</a>!</p>
<p><a href="https://link.segmentfault.com/?enc=pKlLdr9TLOCzw7GaQbet%2Fg%3D%3D.xHPyz%2Bd5TcgZ5Bcqp4EY9gEA6639EKRq22dSqzYl0CNVKgMVMNzBwcmN22HKiWk1" rel="nofollow"><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=N0YgkWOqcR9j3X0O28%2BzBQ%3D%3D.Xe4c%2FqFiNllhKrZYgwZNLHaAzCeagEpn4s7mBrCbGLmdtcmF%2ByjtxffP51W1pr3iyLmaa4GzL%2B0a3oal8M26r81h1FMh%2B87y0T5jTOptFLA%3D" rel="nofollow">https://blog.fundebug.com/2019/07/08/report-http-error-by-fundebug-notify/</a></p>
Fundebug前端异常监控插件更新至 1.9.0,支持监控 HTTP 慢请求
https://segmentfault.com/a/1190000019675891
2019-07-05T15:00:32+08:00
2019-07-05T15:00:32+08:00
Fundebug
https://segmentfault.com/u/fundebug
4
<p><strong>摘要:</strong> <strong>1.9.0</strong>新增 <a href="https://link.segmentfault.com/?enc=Tb3LWOTzsvR2tHxCo7lb7Q%3D%3D.5NIiK9ayXh0%2FEA1Ex95ruc9o0ijCjTkFLlEA2ec3MNOprlyOCzGLkJI5AtrqemseAM7ASm3xvrgY2VPj2inHPsHptvAoq%2BErQOGkVEZZhSc%3D" rel="nofollow">httpTimeout</a> 配置选项,支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG。</p>
<p><img src="/img/remote/1460000019373421?w=900&h=383" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=hYQS4SkiAgp808UqG%2FvVBg%3D%3D.cA5Aq8Z28%2BgHkM9uPsqcLY0wGx%2FiInBb8uRevASF9ns%3D" rel="nofollow">Fundebug</a>提供专业的前端异常监控服务,可以第一时间捕获线上环境中小程序的异常、错误或者 BUG,及时给开发者推送报警,帮助您快速修复 BUG。</p>
<p><a href="https://link.segmentfault.com/?enc=k00MLpNT9YMqk8Iy4vgtVg%3D%3D.UuDT0ABzEkfkGVE0JhSb9lx9o%2Bc4se6%2BOfec5YhhoUo%3D" rel="nofollow">Fundebug</a>的前端异常监控插件更新至<strong>1.9.0</strong>,新增<a href="https://link.segmentfault.com/?enc=yzrBiAYn2MRlhvDjT3yi5g%3D%3D.rX3CEN2sIfd%2BBai3yLtFKXLfcPsoYGp1qOt4lgq8WH3woor7hdxqgecRmTlXvp3sN%2FVkvy7GsrVQBVD7vuuU4snUIBGrzlQoVMnO5tA9gWw%3D" rel="nofollow">httpTimeout</a>配置选项,支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG,请大家及时更新!</p>
<h3>监控 HTTP 慢请求</h3>
<p>Fundebug 专注于程序异常监控,暂时无意于提供全面的性能监控服务。但是,当 HTTP 请求过慢,导致用户体验很糟糕时,也可以理解为一种广义的 BUG。HTTP 请求的性能问题,可能是代码的算法不够好导致的,可能是业务逻辑有问题,可能是应用架构不合理,有可能是数据库的索引不合理导致的,还有可能是其他原因,这些都是技术层面的”BUG“,需要开发者及时处理。</p>
<p>当然,监控所有 HTTP 请求的响应时间不是我们 Fundebug 需要做的事情,因此我们只支持监控慢请求。用户只需要配置一个阈值<a href="https://link.segmentfault.com/?enc=2AoGoux0LSqlfCMlJ33e7A%3D%3D.en22UC%2F8aoBWLLKaoaNk7AXAAaOLGidffafN114BDGPovElJav%2FYazv1LNpVBZSHNHypocyppIW5%2FWwEImVNZTnudW8RzTD1oqU%2FtEvMXjw%3D" rel="nofollow">httpTimeout</a>,所有响应时间超过阈值的 HTTP 请求都会上报的 Fundebug,这样可以帮助开发者发现一些慢请求,及时优化性能。</p>
<p>互联网由粗放式发展逐渐转向精细化发展,这也要求开发者对线上应用进行更加严格的监控,尽量优化性能、减少BUG,这也才能提高产品质量,赢得客户的信任,欢迎大家<a href="https://link.segmentfault.com/?enc=ua0kkeAM4Tr8SkMlWUxzJQ%3D%3D.IS5lYt%2BWlhtZKvI3xFoBFhYhGkL5K5aMLW3IWhlS8xRULUrE6Nmih%2Fa7U2sERefu" rel="nofollow">免费试用</a>Fundebug的前端异常监控服务。</p>
<h3>httpTimeout</h3>
<p>监控 HTTP 慢请求的正确方式是通过 Fundebug 的配置选项<a href="https://link.segmentfault.com/?enc=nSf6pENPar8BS5QcKK1UOg%3D%3D.lhJBOYgDVCZkHJY1PE%2BhE1Z7W76OEHukxb9%2FBrCdK4J3pzSMh9wO5SfVOj0aOJxzFJoiHNKnQB6NXIRSVcOENlilVTF%2FxAECjQpd1IXa1XA%3D" rel="nofollow">httpTimeout</a>来实现。</p>
<p>httpTimeout 类型为 Number,单位为毫秒(ms)。</p>
<p>如果你希望监控较慢的 HTTP 请求,则可以通过<a href="https://link.segmentfault.com/?enc=ZJJBEfJcZCksvj3lq6Zbew%3D%3D.b4%2B2X16P%2B41oLs9I6lXCtX7n2DbYIvQlD9mu6Xl7gupB%2FQmKd7bPJGsNEay91P0Ur5IkqJpRJCqIFC%2B6OUXXNNr%2FNRgIMPrC%2Fsl384a3tlc%3D" rel="nofollow">httpTimeout</a>配置阈值,比如 1000:</p>
<pre><code class="js">if ("fundebug" in window) {
fundebug.httpTimeout = 1000;
}</code></pre>
<p>则所有响应时间超过 1000ms 的请求都会上报到 Fundebug。</p>
<p>例如,Fundebug<a href="https://link.segmentfault.com/?enc=ZlvGHeImH3PxvdbX%2BuETtg%3D%3D.6dL10fi4TXdC7w8b8uPOaUiLN7VMKaZEYnuyB79fhSCM7ILXClQR9kyxCBfu%2FCfSCvG%2FgUG3nELu60wNfmDr7A%3D%3D" rel="nofollow">上传Source Map</a>的接口比较慢,这是因为source map文件太大导致的,这个问题也需要进一步优化,比如可以在前端压缩source map文件之后再上传。</p>
<p><img src="/img/remote/1460000019675894?w=1009&h=611" alt="" title=""></p>
<p>最后,感谢 Fundebug 用户<strong>yaoqi</strong>的反馈。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=EQxu%2FxJWn4X%2BNMLzhqvkYQ%3D%3D.b6d9Sn4mSr%2FTpd4FgKMEzvCCJJFxtauZEHQMjK3V3uswg96QIzF23AH%2FwAias80OoUw0y8%2BxglzuzffbO2cJpnTi9IU4uULynMKXtHWs%2FiI%3D" rel="nofollow">Fundebug 文档 - httpTimeout</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=itdlFvDSXZfhegIPPRlHHQ%3D%3D.G4ct0Vs2IgIOkIj0r3pxuVxev%2FUr9Y%2F50dv1yFK%2FB0Y%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多知名企业。欢迎大家<a href="https://link.segmentfault.com/?enc=sZPwdAKUqiwbQv0eAmtVUw%3D%3D.1t0NoTNaZ0UF%2FsUsr0d%2BVKvBzOk71uOgLQkz8Fd9dJLRABdqKtzC5GMbuTpIAAP0" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=v9S52194Vbmlz76mabpPYQ%3D%3D.wgGF6cumV2kqi8UZQLUHNuwxTlbVLBYX%2FEciAY%2BZF5M%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=sFasBoj%2FyPrtxbIdg2GXGQ%3D%3D.9lXFjC%2BjEBnmn5OPMEW1GjetiMAlscwNkMK0EFYZDS0lopQKnSlyGL1%2BH4dxsQ6X8zPv3kMYUMfZ2vCLunNerh9X9SIQKf%2FQnjx89%2Fpm5yg%3D" rel="nofollow">https://blog.fundebug.com/2019/07/05/fundebug-javascript-1-9-0-httptimeout/</a></p>
JavaScript深入浅出第3课:什么是垃圾回收算法?
https://segmentfault.com/a/1190000019650517
2019-07-03T10:50:10+08:00
2019-07-03T10:50:10+08:00
Fundebug
https://segmentfault.com/u/fundebug
15
<p><strong>摘要:</strong> JS是如何回收内存的?</p>
<p><strong>《<a href="https://link.segmentfault.com/?enc=U5yo9R4ZKN3zAHsM3I%2B39g%3D%3D.qV7DWMgjnQSpeqGmi3hn3RWZNjnmkRGuZ9RneqBfEnpHFsl8WFQR%2BMJx%2BGaahjEUkI4TQg6DUiaGNXIhRKsUjotm7SXOIkGRCm4q5YGxfBI%3D" rel="nofollow">JavaScript深入浅出</a>》系列</strong>:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=%2FTSPB%2BEcOLJ4cnXH%2BxGv4Q%3D%3D.axRCj1agWB0RTFuPjxC%2FHpIYLR1qH7KSXyw%2BUcxb4LVv%2Fo3u9UAB3obbzkocWPHNyrOI%2BFXaNtU5JtanJwH7oA%3D%3D" rel="nofollow">JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?</a></li>
<li><a href="https://link.segmentfault.com/?enc=7iXfWOmzvQmILgFrJBEYfg%3D%3D.WzfsJZvFDC5xTiYzNSIDj1fuhhKQfdFZPS80tLyTt7DyUjcoKaeWcRTi5%2FH37YJJJXlK5RpHLw6hwqisplh%2FhHF7doXHZUDbKtenQmLG6KU%3D" rel="nofollow">JavaScript深入浅出第2课:函数是一等公民是什么意思呢?</a></li>
<li><a href="https://link.segmentfault.com/?enc=nQ7Xh7f6ewEVkUfcw6BDeg%3D%3D.uDzElY3%2FL5A3Yn%2F8EouwismEJji0GE0roE3Q15KdMtkG1PHRp4p7Q3UUauTr3iIXQ%2Flqpw3cafbsEApElawAR0n3nMVjDsVfrv2zgFIFDI4%3D" rel="nofollow">JavaScript深入浅出第3课:什么是垃圾回收算法?</a></li>
</ul>
<p>最近垃圾回收这个话题非常火,大家不能随随便便的扔垃圾了,还得先分类,这样方便对垃圾进行回收再利用。</p>
<p>其实,对于写代码来说,也有<strong>垃圾回收(garbage collection)</strong>这个问题,这里所说的垃圾,指的是<strong>程序中不再需要的内存空间</strong>,垃圾回收指的是回收这些不再需要的内存空间,让程序可以重新利用这些释放的内存空间。</p>
<h3>手动管理内存</h3>
<p>对于C这种底层语言来说,我们可以使用malloc()函数分配内存空间,当所分配的内存不再需要的时候,可以使用free()函数来释放内存空间。</p>
<pre><code class="c">#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
int main ()
{
int *p, i, n, sum;
while (TRUE)
{
printf ("请输入数组长度: ");
scanf ("%d", &n);
p = (int *) malloc (n * sizeof (int)); // 分配内存空间
sum = 0;
for (i = 0; i < n; ++i)
{
*(p + i) = i + 1;
sum += *(p + i);
}
printf ("sum = %d\n", sum);
free (p); // 释放内存空间
}
return 0;
}</code></pre>
<p>示例代码很简单,输入一个整数n,程序计算<strong>1、2、3...n</strong>的和。大家可以在<a href="https://link.segmentfault.com/?enc=E4Hi%2F%2BUBZQu7PVLoR%2Fwf4A%3D%3D.Hh2E2MRoKKgZUsv2Q40Nrok97B5ty8r%2FtoKns9nKmLHRvxLLXM4kEbrZQclfUJHS" rel="nofollow">Online C Compiler</a>上运行这段代码。</p>
<pre><code class="bash">请输入数组长度: 36
sum = 666
请输入数组长度: 100
sum = 5050 </code></pre>
<p>如果我们不去调用free()函数释放内存的话,就会导致<strong>内存泄漏(memory leak)</strong>。每个while循环中,指针p都会指向新分配的内存空间。而p之前指向的内存空间虽然没用了,但是并不会被释放,除非程序退出。如果while循环一直执行下去的话,内存早晚不够用。</p>
<h3>垃圾回收算法</h3>
<p>如果让我们去手动管理内存,那不知道要写出多少BUG,内存分分钟用完。还好现代编程语言,比如Java, Python, Go以及JavaScript,都是支持自动垃圾回收的。也就是说,这些语言可以自动回收程序不再需要的内存空间,这样既减轻了开发者的负担,也有效避免了内存泄漏。</p>
<p>其实,早在C语言诞生之前的1960年,图灵奖得主<a href="https://link.segmentfault.com/?enc=siIFpB4czHr4Xkqm9Fd9MQ%3D%3D.Cm5FvSK4Ki5gmUesok18Zh2qod%2BU6LYhElBqgFsMu7HvrA3zDKZJV1WN%2BAj8lvzojIRCdsptyQcXFVtE4B%2Bjaw%3D%3D" rel="nofollow">John McCarthy</a>就在Lisp语言中实现了自动垃圾回收算法。算法本身其实非常简单,标记那些程序访问不到的数据,回收它们的内存空间。但是,垃圾回收算法把程序员从硬件层(内存管理)解放出来了,这种理念还是很先进的。</p>
<p>对于垃圾回收算法来说,最困难的问题是<strong>如何确定哪些内存空间是可以回收的,即哪些内存空间是程序不再需要的</strong>,这是一个<strong>不可判定问题(<a href="https://link.segmentfault.com/?enc=EmJBI9ePSmw9%2BR6bTU5xvQ%3D%3D.Ez7CBARR4GkIY2EEq8eu10TkwglHVRprh3%2F%2FPeoz3SVzlI3KTEmo5qER8d3OQavXcxFoF3rogUQc0AO%2BtVCcog%3D%3D" rel="nofollow">undecidable problem</a>)</strong>。所谓不可判定,就是没有哪个垃圾回收算法可以确定程序中所有可以回收的内存空间。</p>
<p>McCarthy简化了判定数据是否需要的问题,将其简化为判断数据是否能够访问。如果程序已经不能访问某个数据了,那这个数据自然是不再需要了。但是,这个逻辑反过来是不成立的,一些可以访问的数据也有可能其实程序已经不再需要了。</p>
<p>McCarthy的垃圾回收算法现在通常被称作<strong>Mark-and-Sweep</strong>,它是现在很多语言(Java, JavaScript, Go)的垃圾回收算法的原型。</p>
<h3>JavaScript的垃圾回收算法</h3>
<p>对于JavaScript来说,我们是不需要手动管理内存的,因为JavaScript引擎例如<a href="https://link.segmentfault.com/?enc=tu2%2BQo0nshtFjGBdmsKJIw%3D%3D.Yo61zsJ75WXVtmorNggS7A%3D%3D" rel="nofollow">V8</a>与<a href="https://link.segmentfault.com/?enc=sMkSLM5Du5bZuLkbIQ8%2B7A%3D%3D.Y5BjlsIPqXNdhMOkffyJ6g7ApQOPKWJKLdVRZp5b079gjaxEviox3Rpl3LPEdn0AKOqQjzMHGUtWwsFDL8SxK9A78BNPMCvVmufbPVH%2FKQc%3D" rel="nofollow">SpiderMonkey</a>都会自动分配并回收内存。</p>
<p>比较古老的浏览器,比如IE6和IE7使用的垃圾回收算法是<strong>reference-counting</strong>:确定对象是否被引用,没有被引用的对象则可以回收。这个算法无法回收Circular Object,有可能会因此造成内存泄漏:</p>
<pre><code class="javascript">var div;
window.onload = function() {
div = document.getElementById('myDivElement');
div.circularReference = div;
div.lotsOfData = new Array(10000).join('*');
};</code></pre>
<p>div对象的circularReference属性指向div本身,因此div对象始终“被引用”。如果使用<strong>reference-counting</strong>垃圾回收算法的话,则div对象永远不会被回收。最新的浏览器很早就不再使用reference-counting,因此Circular Object无法回收的问题也就不存在了。</p>
<p>目前,主流的浏览器使用的垃圾回收算法都是基于<strong>mark-and-sweep</strong>:</p>
<ul>
<li>root对象包括全局对象以及程序当前的执行堆栈;</li>
<li>从root对象出发,遍历其所有子对象,能够通过遍历访问到的对象是可以访问的;</li>
<li>其他不能遍历对象是不可访问的,其内存空间可以回收;</li>
</ul>
<p>算法思想并没有超越McCarthy半个世纪之前的设计,只是在实现细节上做了大量的优化,V8的垃圾回收模块Orinoco<a href="https://link.segmentfault.com/?enc=cTOWHg8WCSBShPrZRdUb6w%3D%3D.t02ALHqveXd0g0w7Qag7IuCzpNW0GdCO6qJDEKe1ebo%3D" rel="nofollow">大致是这样做的</a>:</p>
<ul>
<li>采用多线程的方式进行垃圾回收,尽量避免对JavaScript本身的代码执行造成暂停;</li>
<li>利用浏览器渲染页面的空闲时间进行垃圾回收;</li>
<li>根据<a href="https://link.segmentfault.com/?enc=Aff9sUXsOAc9Kqxv%2BjRf%2BA%3D%3D.LBym97wtFCpfLgiJktZUSzE9VPAVqmWBpwuqSo57qLslHrdo3l0jMxG9MjV%2FkdjKXWf2rApZhfm7EonUUgh0bTLEm1jd9iEhFFH2N4WdEZHuYj2KMEIeEfqx4wVVickf" rel="nofollow">The Generational Hypothesis</a>,大多数对象的生命周期非常短暂,因此可以将对象根据生命周期进行区分,生命周期短的对象与生命周期长的对象采用不同的方式进行垃圾回收;</li>
<li>对内存空间进行整理,消除内存碎片化,最大化利用释放的内存空间;</li>
</ul>
<p>JS引擎的垃圾回收算法已经非常强大了,所以我们作为JavaScript开发者基本上感受不到它的存在。</p>
<h3>观察JavaScript垃圾回收算法</h3>
<p>我们通过Chrome开发者工具实际感受一下垃圾回收算法的效果。</p>
<p><strong>测试1:</strong></p>
<pre><code class="javascript">var str = new Array(100000000).join("*");
setInterval(() => {
console.log(str[0]);
}, 1000);</code></pre>
<p>str是一个超长字符串,因此会占有不少的内存空间。代码里面写了一个setInterval,是为了让这段代码永远执行下去,程序不退出。这样的话,字符串str永远在使用中,永远是可以访问的,那它的内存空间就不会被回收。</p>
<p>我使用的是Chrome 75,在其开发者工具的Memory的Tab下,使用Take heap snapshot可以获取内存快照:</p>
<p><img src="https://image.fundebug.com/2019-07-03-01.png" alt="" title=""></p>
<p>可知,内存占用了97MB,且我们可以在其中找到str这个超长字符串。</p>
<p><strong>测试2</strong></p>
<pre><code class="javascript">var str = new Array(100000000).join("*");
setInterval(() => {
console.log(str[0]);
}, 1000);
setTimeout(() => {
str = "******";
}, 10000);</code></pre>
<p>在setTimeout的回调函数中,我们对str进行了重新赋值,这就意味着之前的超长字符串就不可访问了,那它的内存空间就会被回收。</p>
<p>在代码运行10s之后,即str重新赋值之后进行快照:</p>
<p><img src="https://image.fundebug.com/2019-07-03-02.png" alt="" title=""></p>
<p>可知,内存只占用了1.6MB,且我们可以在其中找到str字符串,它的长度只有6,因此占用的内存空间非常小。</p>
<p>想象一下,如果不再需要的内存空间不会被回收的话,1T的内存都不够用。</p>
<p>关于JS,我打算花1年时间写一个系列的博客<a href="https://link.segmentfault.com/?enc=TSWr%2BD4ItmIF2dp%2Fy6nXDg%3D%3D.brRddqsN6fNB8s8MPqWziY3Yw%2FrF3GZCqFZo8LvXN%2Bs534%2BXfI%2BrW8fpKZrc0Hvcm9Zo2CcuIQUlhCYvzJhCO%2FUYQKCpiEpgyCvjedELJC0%3D" rel="nofollow">JavaScript深入浅出</a>,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。欢迎添加我的个人微信(KiwenLau),我是<a href="https://link.segmentfault.com/?enc=f1%2Bqr7%2BcW9P%2F8Q1wiUx%2FDg%3D%3D.z0fSLSZo1KiJzRHDAn2ENcqdZMOV4m6azkR9FBcjQ%2B8%3D" rel="nofollow">Fundebug</a>的技术负责人,一个对JS又爱又恨的程序员。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=lZHInRhJr1aBsqsOgzyI6A%3D%3D.CgDh5M3sbrrnYgr0WFuBjet4di2Hy9BdOxX1a8Vw0qBDD8g2CjElnWYDAP18Y8UsdsH2YQyBN15uSLcIdxt4LN9BkVxqTomtn5BqdGRtNpk%3D" rel="nofollow">MDN:Memory Management</a></li>
<li><a href="https://link.segmentfault.com/?enc=J4mtU7VeRq3bbgT2smg%2Feg%3D%3D.XEBhzQaQqS7ASqo71lFQogvlT4Q07FQ4ig%2BT%2FFNb3vmbe8LmA4G51X9cT4P%2Fy2sa7XPMZb96Chswsn%2FLI3TMHoH1ExFgo%2BrqpsEQbmRWjDg%3D" rel="nofollow">为什么Lisp语言如此先进?</a></li>
<li><a href="https://link.segmentfault.com/?enc=7G0EqFYONFLqKJzthv%2BhMg%3D%3D.Ikx%2BpNRv%2BJiRRof%2BJCPR0YJwlRIMOrOmvLleEfRh0AbexRv0HIkwwNDBA6edwz0upVu2JH9rYY3qPITMZWph6Q%3D%3D" rel="nofollow">Recursive Functions of Symbolic Expressions Their Computation by Machine(Part I)</a></li>
<li><a href="https://link.segmentfault.com/?enc=CLPYEm872N%2FnPHpyJJMcSw%3D%3D.u%2F70mx3n%2B0IH4O7GoVFmp6aJsg9vHiTcjmYO6nGH4SA%3D" rel="nofollow">Trash talk: the Orinoco garbage collector</a></li>
<li><a href="https://link.segmentfault.com/?enc=DjsP9H%2FzKTj3M3REuzy3XQ%3D%3D.d513irvfCrOKcqovv9idq9gRkS1teOUtNQT0pp8AGQ7ySegTB6rKGyQl4Kgqvwh%2B" rel="nofollow">Idle-Time Garbage-Collection Scheduling</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=xGNdl%2Fu3EUBPv%2B1CYohoGg%3D%3D.7KXEHFuy3sGQA88q%2Fk2SeK%2FBYSOLiDwNAwYs934Jo9U%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=6LPzkmFTsRc%2Bk5OHY0XLpg%3D%3D.qM9CivYq1hUo5zUZ4APQXlGArhiLa817xqM97SlC23cwbUB0nnSheKQobfiDDD%2BB" rel="nofollow">免费试用</a>!</p>
<p><img src="https://static.fundebug.cn/wechat_slogan.png" alt="img" title="img"></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=%2BQGNsBrEE0y78M4hQZoUgQ%3D%3D.knfXOLVCcF24Fe9%2Fr41Kk4y7tOebYS9U%2FXgdSeE9R1IaohjBA1VfSAM1oX7ZRxsEJpOZx0OT0Q1QS9LThNHl9iXw2pnAxZkweaNI%2F8lCxsY%3D" rel="nofollow">https://blog.fundebug.com/2019/07/03/javascript-garbage-collection/</a></p>
监控微信小程序wx.request请求失败
https://segmentfault.com/a/1190000019627090
2019-07-01T10:16:31+08:00
2019-07-01T10:16:31+08:00
Fundebug
https://segmentfault.com/u/fundebug
4
<p>在微信小程序里,与后台服务器交互的主要接口函数是<code>wx.request()</code>,用于发起 HTTPS 网络请求。其重要性不言而喻。然而,却经常遇到请求失败的问题,笔者特意谷歌"wx.request 请求失败",可以搜索到很多相关的文章,下面列出一些:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=puHaHWV%2F2qz%2BlpJ5c72G1Q%3D%3D.QQ3Nuv%2B%2F73cNTgRTTYDDpP6oVFOpiCYUj7ufdOmTnyAKpyb9tzcYyvPIrSIutqw2kiks3bigiGyZQCj2y%2F10UMrPXhCecYM4pkFYPWVXk6eNk9usu1Ea0Z0rOmQBZvT%2B" rel="nofollow">wx.request 失败| 微信开放社区</a></li>
<li><a href="https://segmentfault.com/q/1010000016785650">微信小程序 wx.request 请求失败- SegmentFault 思否</a></li>
<li><a href="https://link.segmentfault.com/?enc=xT2902lRM3y8r9F80ETzxA%3D%3D.mWcH5uP1onQ%2BJNtHwsQNOF%2BPh60jK8DfHQ3T3tr6f7Cvh7pEGT2jNKCbmtN6ZCwH2QAvkZG8KNWBSH2uaE7lmQ%3D%3D" rel="nofollow">小程序部分机型小程序用户无法发起 wx.request 请求,网络错误问题 ...</a></li>
<li><a href="https://link.segmentfault.com/?enc=bG1%2F1wAzJHUVnRCMsKpsjw%3D%3D.pBbJxaRS1iDP0JtMdv%2BhI%2Fl6oK2xmHpyOYQvBxNd4OXkyl%2FJRGguKCBaiklIfjFa7CnyUMhb9rBdN48CEn%2BgHV1Cgh%2Bx41eLWFiToGhfHZntJnXwMNXGYM277a%2BW2AQyYwAoQtRoj3oCN2eCXADDdg%3D%3D" rel="nofollow">wx.request()失败,request:fail。_微信小程序开发</a></li>
<li><a href="https://link.segmentfault.com/?enc=bJzXTn0sCjd5cw3BacmN%2BA%3D%3D.2MWMyB9rl4ThyTY7XR8jn9rJzIyX2hXaL70l6E92lywiIDLyjDe7dfz%2Fy3E8lxG8yh03L9oorwe3YoB3bcngdx3nP1ITJKofYkiRanDIOYNdkQxkPs3mUBAbMkQR5PmUPytbBGa0ly3HAMIohnotOg%3D%3D" rel="nofollow">request:fail 合集(各种 request:fail 问题)</a></li>
<li><a href="https://link.segmentfault.com/?enc=cE7RuLFAoiHIBSJmZ0x3Eg%3D%3D.payd7jOcNv7KfmSHG9Gzp6hApQQQ9O%2B7hzHkJWEAURtTPl28VrkOm%2BBD0YTcZM5E" rel="nofollow">微信小程序之 wx.request:fail 错误排查- 简书</a></li>
</ul>
<p>有些事开发时候遇到,有些是产品上线后遇到。线上的情况比开发和测试的时候复杂的多,失败的原因可能各种各样。既然测试无法 100%保证上线不会出问题,我们唯一要做的就是及时发现和快速响应。</p>
<p>微信小程序运维中心提供了错误日志记录,但功能还是比较有限。只有简单的统计和错误展示功能,而往往仅仅靠报错信息是无法清晰理解错误成因的。这个时候使用强大的第三方监控服务就很有必要了。</p>
<p><img src="https://image.fundebug.com/2019-07-02-wechat-dev-request-fail.png" alt="" title=""></p>
<h3>小程序 Demo</h3>
<p>我们使用一款由<a href="https://link.segmentfault.com/?enc=vmaQCI0SAxp%2Fq3g5HVFtHA%3D%3D.oBsKtfz0vBQsUODTWOJLcL0va9camyd%2FamSXWym%2BVJk%3D" rel="nofollow">jectychen</a>开发的<a href="https://link.segmentfault.com/?enc=opaC1Yte4Gs%2FEuCsplEqgg%3D%3D.JqzHbMhFwfMBok%2BPzHJBKGiUOLRbV1EMFWtqalvR698iCMNzNVVmCcBx6TmmXMak" rel="nofollow">wechat-v2ex</a>来做演示,v2ex 数据 api 基本上使用了 samuel1112 的仓库<a href="https://link.segmentfault.com/?enc=hZz6obtbQ%2BSF%2Fao5jvA%2B4g%3D%3D.FwJwnOVox8%2BoH7Yfz5j3ClkuT4yzoW5O4BAo4nerOk4%2Fj1hcBjA%2FnavdkNKBBzDK" rel="nofollow">v2er</a>里封装的方法。</p>
<p>其运行效果如下:</p>
<p><img src="https://image.fundebug.com/2019-07-02-wechat-v2ex-project.png" alt="" title=""></p>
<p>最左侧本来应该有头像的,可能由于防盗链的原因没有显示出来。</p>
<p>有时候一个微信小程序可能会用到多个第三方服务,从多个域名获取数据。以下两种情况都值得注意:</p>
<ul>
<li>某些接口做了更新没有及时推送通知,该接口的调用就会失败;</li>
<li>服务不够稳定,接口的返回某一时段特别慢;</li>
<li>某些终端用户的数据不符合导致接口失败。</li>
</ul>
<p>因此产品上线以后,对接口的调用进行监控是很有必要的。</p>
<h3>接入监控</h3>
<p>Fundebug 的微信小程序错误监控插件支持监控 HTTP 请求错误:</p>
<ul>
<li>当请求返回的 statusCode 不是 2xx 或者 fail 回调函数被触发的时候,Fundebug 的小程序监控插件会捕获该错误并发送到服务器。</li>
<li>如果接口请求耗时过长,我们也可以配置<code>httpTimeout</code>来监控。</li>
</ul>
<p>要使用 Fundebug 监控,你需要去<a href="https://link.segmentfault.com/?enc=0i2p4B0NuFlPeNwglLnJ0Q%3D%3D.7uxqax5THMVDgxW0ZPkpJBItVk1Chmmyqs31Z836%2FcM%3D" rel="nofollow">Fundebug</a>网站注册账号并创建一个微信小程序监控项目,然后按照提示接入插件。你需要下载微信小程序监控的 JS 脚本放入到自己的项目中,然后引入并通过<code>fundebug.init()</code>函数作必要的配置。</p>
<pre><code class="js">var fundebug = require("./utils/fundebug.1.3.1.min.js");
fundebug.init({
apikey: "YOUR-API-KEY",
monitorHttpData: true,
httpTimeout: 2000,
monitorMethodCall: true,
monitorMethodArguments: true,
setSystemInfo: true,
setUserInfo: true,
setLocation: true
});</code></pre>
<p>插件默认会监控 HTTP 请求错误,并上报 Header 部分的信息,我们无需做配置。为了方便 Debug,我们配置<code>monitorHttpData</code>来记录 body 部分的信息;我们将<code>httpTimeout</code>设置为 2000 毫秒,超过该时长的请求会被上报到服务器。</p>
<h3>Request:fail 错误</h3>
<p>为了演示<code>wx.request</code>返回 request:fail 错误,我特意将<code>utils/api.js</code>中的<code>HOST_URI</code>改错。</p>
<p><code>var HOST_URI = 'https://www.w2ex.com/api/';</code></p>
<p>然后保存运行。Fundebug 收到上报的错误,该请求花了 7072 毫秒,然后返回请求失败。</p>
<p><img src="https://image.fundebug.com/2019-07-02-request-fail.png" alt="" title=""></p>
<p>通过用户行为可以更加清楚地了解整个小程序的运行过程:</p>
<p><img src="https://image.fundebug.com/2019-07-02-request-fail-user-behavior.png" alt="" title=""></p>
<h3>404 错误</h3>
<p>这次,我将获取最新话题的接口做点更改,故意将<code>latest</code>写出<code>lastest</code>:</p>
<p><code>var LATEST_TOPIC = 'topics/lastest.json';</code></p>
<p>保存运行,Fundebug 捕获该错误并上报到服务器:</p>
<p><img src="https://image.fundebug.com/2019-07-02-404.png" alt="" title=""></p>
<h3>参数错误</h3>
<p>获取某一个话题详情的时候,应该传入对应的 id。如果 id 是 null、undefined、或则本来是数字我们传入字符串,看看结果怎么样。</p>
<p>下图可知当我们将参数 id 设为<code>undefined</code>的情况下,接口返回 404。并返回消息:</p>
<pre><code class="json">{
"message": "Object Not Found",
"status": "error"
}</code></pre>
<p><img src="https://image.fundebug.com/2019-07-02-404-parameter-error.png" alt="" title=""></p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=RXUfrwpuoBCaziTRCUOvUg%3D%3D.WEj9db66TLuAR%2FERUIPNu4tM0C%2FInEI1ctBWGHcBV0k%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!</p>
<p><a href="https://link.segmentfault.com/?enc=ffLp2W48pRLGrot3RorGNw%3D%3D.J%2F4b0ze4lBh4oqYIYmYMOx7a8cv9UkQR2%2FyrraYjygejL45zrliyyfMWkYPwxmtV" rel="nofollow"><img src="https://static.fundebug.cn/wechat_slogan.png" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者 <strong>Fundebug</strong>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=vLEZLdkJZLd0shWKClH2EA%3D%3D.KhILVuCo%2BY565V5fyc6Pi%2BgxQH3DMj4reEWVYEcK9UkKx05wDX1ohoIeNPdgRk3MsrYsxYrh4iTGWNlncLr3Aw%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/07/01/monitor-wx-request-fail/</a></p>
监控微信小程序中的慢HTTP请求
https://segmentfault.com/a/1190000019595543
2019-06-27T10:09:01+08:00
2019-06-27T10:09:01+08:00
Fundebug
https://segmentfault.com/u/fundebug
4
<p><strong>摘要:</strong> 请求时间太长,影响用户体验,使用 Fundebug 监控慢请求。</p>
<p>Fundebug 的微信小程序监控插件在 0.5.0 版本已经支持<a href="https://link.segmentfault.com/?enc=vj3AF2DHcY6mAlbffAy%2BQw%3D%3D.24aTxnaKgMSFqvdludgDCSPuavDUBMpkG0OQQYIVDNsCluMQqgZ%2FDck7Jt6MCF2m" rel="nofollow">监控 HTTP 请求错误</a>,在小程序中通过<code>wx.request</code>发起 HTTP 请求,如果请求失败,会被捕获并上报。时隔一年,微信小程序插件已经更新到 1.3.1, 而且提供了一个非常有用的功能,支持<a href="https://link.segmentfault.com/?enc=dl1CF2N%2BM3M8Dfb00qH0BA%3D%3D.lkZmGi9GggaCKCR4hzKTsHuhkv9%2Bfdlcwt1OS5fDy2VTgEjPII13o0LSFlnWDjh1bI2%2BFeb6a7xeyE1vawdW17PgoBV%2FWw30MmV4lJG%2F44Q%3D" rel="nofollow">监控 HTTP 慢请求</a>。对于轻量级的性能分析,可以说已经够用。</p>
<p>本文我们以一个<a href="https://link.segmentfault.com/?enc=kichbZxSnWsNrVmUT%2FIFvg%3D%3D.G2bTqus0qup%2BppD5yyOxHRj%2BkBBrX7HMeLL6fw6MwEU6zcChdiXYyi4z7wM8GWUX" rel="nofollow">天气微信小程序</a>为例(由<a href="https://link.segmentfault.com/?enc=nzEOpJGdzmZz46azc4WF4A%3D%3D.eiRWz5b7qajWbAYj4yLkd0mDjHzFWgvH8IM5LiDyIUg%3D" rel="nofollow">bodekjan</a>开发),来演示如何监控慢请求。<code>bmap-wx.js</code>中的<code>weather()</code>函数调用百度地图小程序 api 提供的接口来获取天气预报信息。</p>
<p><img src="/img/remote/1460000019595546?w=1523&h=726" alt="" title=""></p>
<h2>接入监控</h2>
<p>由于使用百度的 api,我们无法确认该接口的稳定性,可能有时候会特别慢,导致天气信息显示不出来。于是,我们使用 Fundebug 来监控请求过慢的情况。接下来,我们来演示如何监控慢请求。注册账户后,记得要在创建项目是选择“微信小程序”这一项目类型。</p>
<p><img src="/img/remote/1460000019595547?w=1368&h=1372" alt="" title=""></p>
<p>根据指示完成接入流程:</p>
<p><img src="/img/remote/1460000019595548?w=1400&h=916" alt="" title=""></p>
<p>在<code>app.js</code>顶部加入下面的代码(记得将 apikey 替换成你自己的):</p>
<pre><code class="js">var fundebug = require("./utils/fundebug.1.3.1.min.js");
fundebug.init({
apikey: "YOUR-API-KEY",
monitorMethodCall: true,
monitorMethodArguments: true,
monitorHttpData: true,
setSystemInfo: true,
setUserInfo: true,
setLocation: true,
httpTimeout: 200
});</code></pre>
<p>虽然<code>init()</code>函数只要设置<code>apikey</code>即可使用,但是为了最大程度发挥监控的威力,我们不妨多设置一些监控选项。<br>微信小程序插件有很多的可配置项,由于涉及到数据,默认处于关闭状态。我们可以监控函数调用(monitorMethodCall),以及函数调用的参数(monitorMethodArguments),监控 HTTP 请求的 Body 中的数据(monitorHttpData),获取系统信息(setSystemInfo)、用户信息(setUserInfo)、地理位置(setLocation)。</p>
<h2>监控慢请求</h2>
<p>最后,最重要的一步,配置<code>httpTimeout</code>来监控超过特定时长的请求,httpTimeout 类型为 Number,单位为毫秒(ms)。演示起见,我们将时间设置为 200 毫秒。</p>
<p>在微信开发者工具内运行代码,Fundebug 立马收到报错。小程序发往<code>https://api.map.baidu.com/telematics/v3/weather</code>接口的请求时长为 571ms,超过预设时间 200ms。</p>
<p><img src="/img/remote/1460000019595549?w=2556&h=672" alt="" title=""></p>
<h2>错误详情</h2>
<p>该请求返回代码 200,表明能够正常获取数据。点击该条错误,查看错误详情:</p>
<p><img src="/img/remote/1460000019595550?w=1920&h=914" alt="" title=""></p>
<p>通过上方的统计数据,我们可以知道获取天气信息的接口出现缓慢情况的趋势,影响的用户数量,累计发生的次数。我们可以以此来评估是否需要优化该接口,甚至替换成其它第三方接口来解决这个问题。</p>
<h2>附加信息</h2>
<p>因为配置了 monitorHttpData,所以我们可以查看到请求 body 中的详细数据。当请求失败的时候,有时候需要结合参数来分析失败的原因。</p>
<p><img src="/img/remote/1460000019595551?w=1920&h=755" alt="" title=""></p>
<p>另外,用户行为数据记录了小程序运行的详细状况,特别是函数的调用序列,对于理解出错前程序的执行逻辑很有帮助:</p>
<p><img src="/img/remote/1460000019595552?w=1246&h=2963" alt="" title=""></p>
<h2>关于Fundebug</h2>
<p><a href="https://link.segmentfault.com/?enc=oPK0SWABwmO1K%2FPsWUGqzA%3D%3D.VpqJhT7lvxXjJGpjxuLCptqSOOusOABWOk%2FEnzSVciQ%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=e87lfw99evV%2Ba9jt0NnC2g%3D%3D.L9gD6Y7X2MLsUfaSrsZEkVr977s5r1bEhvQoAjuiaTKrndRwSGXPur%2F32yB02Co4" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></p>
<h2>版权声明</h2>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=SfznQDNdyf74V5lVE6Dp7A%3D%3D.JdBxg3pn2kBDh96JckD19KD0KVLJATWhmpvtQdRfsMU%3D" rel="nofollow"> Fundebug</a>以及本文地址:</p>
<p><a href="https://link.segmentfault.com/?enc=QFNTTTteFTN6tyiddhrAig%3D%3D.GbpbUtiJv4tUUqEcEX42fT7l9jkLcPSI8i6IJAPAB%2BDNPAavSjITuh8dUdjXiHiP79RhvwhyR%2F4kda2iwP7cmIKkDku4dHP3QMYmqR%2FS4mE%3D" rel="nofollow">https://blog.fundebug.com/2019/06/27/monitor-httptimeout-in-weather-miniapp/</a></p>
JavaScript深入浅出第2课:函数是一等公民是什么意思呢?
https://segmentfault.com/a/1190000019573304
2019-06-25T09:46:50+08:00
2019-06-25T09:46:50+08:00
Fundebug
https://segmentfault.com/u/fundebug
6
<p><strong>摘要:</strong> 听起来很炫酷的一等公民是啥?</p>
<p><strong>《JavaScript深入浅出》系列</strong>:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=UVHNRkT2DPRQd5Ztn6lApQ%3D%3D.RCeX6oFeR8eIH3iDdRANQxqvjoEWNjRA5xmoDnCHtDLkIOFI%2FEmoss6qUNGc2psgk7k0Pr6PfvWQs5yUzHjfBw%3D%3D" rel="nofollow">JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?</a></li>
<li><a href="https://link.segmentfault.com/?enc=huUTN7YQLdS7ALeTgEQtBg%3D%3D.mgvuYDqBA0PBEC5hOA%2B7XPDubEloNFRJbpZM69HXSIZZFAqBbRBrvcbVe%2BmN1V%2Fc3KIYAbYBpEUIZ2HrYieWGz6UVgz%2FfwzOmqfdihC0DFE%3D" rel="nofollow">JavaScript深入浅出第2课:函数是一等公民是什么意思呢?</a></li>
</ul>
<p>看到一篇讲JavaScript历史的<a href="https://link.segmentfault.com/?enc=mg1tfPzpjjlFSfNGA9jUCw%3D%3D.nEHVCI4NEqwN%2FeK2in471osxRN18s0ebfh8qAo9PfCUob7bTl4QNj2tvPhDgjRYlyvq6F3xTECEI%2FnrQTfGWlg%3D%3D" rel="nofollow">文章</a>里面提到:<strong>JavaScript借鉴Scheme语言,将函数提升到"一等公民"(first class citizen)的地位</strong>。</p>
<p><strong>一等公民</strong>这个名字听起来很高大上,但是也相当晦涩,这个与翻译也没什么关系,因为<strong>first class citizen</strong>很多人包括我也不知所云。</p>
<p>JavaScript函数是一等公民,是什么意思呢?我来与大家探讨一下,抛砖引玉。</p>
<h3>一等公民的定义</h3>
<p>根据维基百科,编程语言中一等公民的概念是由英国计算机学家<a href="https://link.segmentfault.com/?enc=QQElbrJLkbc366vsIZ1yBw%3D%3D.VaX0qgbVn6KvFuKfRbA6aLOyyLU%2FuVn5Cw8a3iCPGtijav%2BwtVkChpZBb4vMbKWq%2F5sJSe6CMbuRhLSbnE5Q%2FQ%3D%3D" rel="nofollow">Christopher Strachey</a>提出来的,时间则早在上个世纪60年代,那个时候还没有个人电脑,没有互联网,没有浏览器,也没有JavaScript。</p>
<p>大概很多人和我一样,没听说过Christopher Strachey,并且他也只是提出了一等公民的概念,没有给出严格的定义。</p>
<p>关于一等公民,我找到一个权威的定义,来自于一本书<a href="https://link.segmentfault.com/?enc=Gu6TOUGaogiMwhnz8IbrxA%3D%3D.ZZSQo5MkQnnhzKfP3JJGiTIAzs7%2BbfNWKjAwMDmqSEGEiJ9d8H9WMge5VocLOY4g" rel="nofollow">《Programming Language Pragmatics》</a>,这本书是很多大学的程序语言设计的教材。</p>
<blockquote>In general, a value in a programming language is said to have first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.</blockquote>
<p>也就是说,在编程语言中,<strong>一等公民可以作为函数参数,可以作为函数返回值,也可以赋值给变量</strong>。</p>
<p>例如,字符串在几乎所有编程语言中都是一等公民,字符串可以做为函数参数,字符串可以作为函数返回值,字符串也可以赋值给变量。</p>
<p>对于各种编程语言来说,函数就不一定是一等公民了,比如<a href="https://link.segmentfault.com/?enc=0SSlSAPunmS4VJ4TUktH%2Fg%3D%3D.EQ1CJXX3hi30uYY6wkkN3%2FItH3QxbMATHnrRgbGIJRAYxfpJlUpqFC1CFEfTuqJL" rel="nofollow">Java 8之前的版本</a>。</p>
<p>对于JavaScript来说,函数可以赋值给变量,也可以作为函数参数,还可以作为函数返回值,因此JavaScript中函数是一等公民。</p>
<h3>函数作为函数参数</h3>
<p>回调函数(callback)是JavaScript异步编程的基础,其实就是把函数作为函数参数。例如,大家常用的setTimeout函数的第一个参数就是函数:</p>
<pre><code class="javascript">setTimeout(function() {
console.log("Hello, Fundebug!");
}, 1000);</code></pre>
<p>JavaScript函数作为函数参数,或者说回调函数,作为实现异步的一种方式,大家都写得多了,其实它还有其他应用场景。</p>
<p><a href="https://link.segmentfault.com/?enc=HVdxdwMkvR4oNOQlKZyUsQ%3D%3D.2oBV87JB7wlbzximdfo6UpkW%2FL4zJNv%2BCuDRdx6rkXX19BeAju4lxlIcZAF2K0lv5Ellgfh8OmVTZh1yF5Ndk0yf2EyuGzFusNUqT8OikrHUDKfbtaC4S89H8wmpDc6w" rel="nofollow">Array.prototype.sort()</a>在对一些复杂数据结构进行排序时,可以使用<strong>自定义的比较函数</strong>作为参数:</p>
<pre><code class="javascript">var employees = [
{ name: "Liu", age: 21 },
{ name: "Zhang", age: 37 },
{ name: "Wang", age: 45 },
{ name: "Li", age: 30 },
{ name: "zan", age: 55 },
{ name: "Xi", age: 37 }
];
// 员工按照年龄排序
employees.sort(function(a, b) {
return a.age - b.age;
});
// 员工按照名字排序
employees.sort(function(a, b) {
var nameA = a.name;
var nameB = b.name;
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
return 0;
});</code></pre>
<p>这样写看起来没什么大不了的,但是对于JavaScript引擎来说就省事多了,因为它不需要为每一种数据类型去实现一个排序API,它只需要实现一个排序API就够了,至于数组元素大小怎么比较,交给用户去定义,用户如果非得说2大于1,那也不是不可以。</p>
<p>换句话说,如果Array.prototype.sort()只能实现简单数据(比如Number与String)的排序的话,那它就太弱了,正因为可以使用函数作为参数,使它的功能强大了很多。</p>
<p>顺便提一下,实现一个Array.prototype.sort(),可不是什么简单的事情,大家可以看看<a href="https://link.segmentfault.com/?enc=UQr76L2Kxb%2FruRJsKtiO7Q%3D%3D.FUWeNJojt8Sdg0VLfktLQYbzBSB%2Bk3n0umbeff9NCSQ%3D" rel="nofollow">V8是怎样实现数组排序的</a>。</p>
<h3>将函数赋值给变量</h3>
<p>JavaScript是可以定义匿名函数的,当我们定义有名字的函数时,通常是这样写的:</p>
<pre><code class="javascript">function hello() {
console.log("Hello, Fundebug!");
}</code></pre>
<p>当然,也可以将函数赋值给变量:</p>
<pre><code class="javascript">var hello = function() {
console.log("Hello, Fundebug!");
};
console.log(typeof hello); // 打印 function</code></pre>
<p>可知,hello变量的类型是"function"。</p>
<p>在其他的一些<a href="https://link.segmentfault.com/?enc=rIdjzoMA2v8uHVEkYbdepw%3D%3D.RaM%2Bs3kiVi2x04CK0JTwZ8Gjt%2BzD8ko7XsTFHPaR8kpf24VS3bTudK87gVlHn2K8cnEB9lGoiqjN14i%2FDx1DGw%3D%3D" rel="nofollow">First-class function</a>的定义中,还要求函数可以保存到其他数据结构,比如数组和对象中,这一点JavaScript也是支持的。</p>
<blockquote>In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures.</blockquote>
<p>函数可以保存到Object中,就意味着函数成为了Object的方法。我在<a href="https://link.segmentfault.com/?enc=DuHElqlE8v%2BWF84lHGtUcQ%3D%3D.CixR5NPxcSWLhO0M5Ww4RMrQCx5Gr8aY8zYTiscYaUAfUGnDOSun57yjxsJBvTP%2BeAvCrH4njyjWKtTlBygVkg%3D%3D" rel="nofollow">《JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?》</a>中提过,当函数作为Object的方法被调用时,它的this值就是该Object,这1点与Java等面向对象语言是一致的。因此JavaScript在没有<a href="https://link.segmentfault.com/?enc=axGzS2rbwkmsdb8TVc2WcA%3D%3D.JLLlOij%2BmZ9mACMmbhfgb5bIEqsnRumcgiDfHGOLhVV5WdycF2PIrg90XIkAlBaJ" rel="nofollow">Class</a>之前,就在一定程度上是支持面向对象编程的,当然比较弱。</p>
<pre><code class="javascript">var person = {
name: "Wang Lei",
age: 40,
greeting: function() {
console.log(`Hello! My Name is ${this.name}.`);
}
};
console.log(person.age); // 打印 40
person.greeting(); // 打印 Hello! My Name is Wang Lei.</code></pre>
<h3>函数作为函数返回值</h3>
<p>通常来讲,函数的返回值比较简单,比如数字、字符串、布尔值或者Object。由于JavaScript函数是第一公民,因此我们也可以在函数中返回函数。</p>
<pre><code class="javascript">function sayHello(message) {
return function() {
console.log(`Hello, ${message}`);
};
}
var sayHelloToFundebug = sayHello("Fundebug!");
var sayHelloToGoogle = sayHello("Google!");
sayHelloToFundebug(); // 打印Hello, Fundebug!
sayHelloToGoogle(); // 打印Hello, Google!</code></pre>
<p>当我们调用sayHello函数时,它返回值sayHelloToFundebug实际是一个函数,我们需要调用所返回的sayHelloToFundebug函数,它才会执行,打印对应的信息:"Hello, Fundebug!"。</p>
<p>我猜这个地方有人会抬杠,因为示例代码没有必要这么写,因为有更简单的写法:</p>
<pre><code class="javascript">function sayHello(message) {
console.log(`Hello, ${message}`);
}
sayHello("Fundebug!"); // 打印Hello, Fundebug!
sayHello("Google!"); // 打印Hello, Google!</code></pre>
<p>但是这只是一个简单的示例,在一些复杂的实际场景中,在函数返回函数还是很有用的。下面给大家一个简单的示例。</p>
<p>我们Fundebug在<a href="https://link.segmentfault.com/?enc=nSnnTTIqa1U8FihGOKoE%2Fg%3D%3D.GlLM906wtnEBXr%2F76Pa%2BLsGDzilymH82Yc3JT89572oVkhDgnqXeMZ6kS4l3VTAwsowRN8TGkKgUj5RrY5NBnw%3D%3D" rel="nofollow">微信小程序BUG监控插件</a>的时候,把不同<a href="https://link.segmentfault.com/?enc=gF%2BymI0F4TczKsHjkvJgGA%3D%3D.u%2FFGtxDpy7kv%2FZMMJn1QkgM0OgJf%2Fm7gh8RVO3%2B2HbLCLz1%2BttSb83MMAqcxjuy%2F" rel="nofollow">API</a>的定义拆分在不同的文件,但是这些API需要共享一些全局属性,比如用户的<a href="https://link.segmentfault.com/?enc=cCvIHkR78YPstmIoiiRffQ%3D%3D.yOlBkFezwWuS45DS0fxJ8LRnvqmSgg44Mkd7qGrfAoaxxh2w8dUdGbPsTjTZoB4AC8NEvxUDje49YgZMJmYiDQ%3D%3D" rel="nofollow">个性化配置</a>。微信小程序是没有全局变量window的,就算是网页端有window其实最好也不要用,会污染全局作用域。这时候该怎么办?给大家看看定义<a href="https://link.segmentfault.com/?enc=bF%2FRDOD5YUxdhUUHYOZkzA%3D%3D.13xggFxJIVS3DX02FwxJJ3i9AkyzhcHim0mZBTHaMYKaQ%2B163k8jv4Q%2BikDDqpbyoiO81%2FCnroqAuZyVaZGGiA%3D%3D" rel="nofollow">fundebug.test()</a>是怎样定义的吧:</p>
<pre><code class="bash">function defineTestApi(config) {
function testApi(name, message) {
const event = {
type: "test",
apikey: config.apikey,
name: name || "Test",
message: message || "Hello, Fundebug!"
};
sendToFundebug(event);
}
return testApi;
}</code></pre>
<p>我们使用了一个外层函数defineTestApi来共享全局配置对象config,函数中定义的testApi函数则通过return返回。</p>
<p>这里其实也用到了<strong>闭包</strong>,因为defineTestApi函数执行结束之后,testApi函数仍然可以使用config变量,因此config变量的生命周期超越了defineTestApi函数。关于闭包的详细介绍,我会在这个系列的后续文章中介绍。</p>
<p>因此,<strong>在函数中返回函数,还是很有用的</strong>。</p>
<p>开发者对待每一个技术点,比如闭包,应该保持谦卑,不要觉得这个也没有用,那个也没有用,其实只是你还没遇到使用场景而已。关于这一点,大家可以看看我的博客<a href="https://link.segmentfault.com/?enc=MeU8faz1xs%2BmFhjKY3AHZA%3D%3D.3L0I4kfHzNimXf16jNjHaDBU3IHckk1QuoFswe4GJw4RymWk84UWTgwRmCnlOh%2Fwpucp%2BLIYg3j7LCUOE6qqqsRmu55RHJweJpsFZ2gkXGQ%3D" rel="nofollow">《聊聊我的第一篇10万+,同时反驳某些评论》</a>。</p>
<h3>函数为第一公民是函数式编程的基础</h3>
<p>函数为第一公民的3个特性我都介绍了,它们确实让JavaScript更加强大,然后呢?JavaScript的骚操作大家见得多了,也不会觉得有什么神奇之处。</p>
<p>其实,函数是第一公民,与大家都听过的<strong>函数式编程</strong>有着密切的关系。</p>
<blockquote>First-class functions are a necessity for the functional programming style, in which the use of higher-order functions is a standard practice. </blockquote>
<p>也就是说,<strong>函数为第一公民是函数式编程的必要条件</strong>。higher-order functions,即高阶函数,就是使用函数作为参数的函数,它在函数式编程中很常见。</p>
<p>至于什么是函数式编程,不是我一句话能讲清楚的,这可以一直聊到计算机的开山鼻祖图灵。要知后事如何,请听下回分解。</p>
<p>关于JS,我打算开始写一个系列的博客,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。也大家欢迎添加我的个人微信(KiwenLau),我是<a href="https://link.segmentfault.com/?enc=UVHsh7WaW9c85Vh265s0nA%3D%3D.YNV87QQpOzFFi7v8X7bCcfTM3Pn0u%2FUFAex%2FQ6mUQsc%3D" rel="nofollow">Fundebug</a>的技术负责人,一个对JS又爱又恨的程序员。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=oOn%2BqX7Hs%2FuY0fEkYfCbTQ%3D%3D.8JEa3xHTomdHFGX8o86zUiHWC1iqjlD5HwTq6HH4PTuOtlBIps5k4Vef%2BOYQNjXjjo56n3G5zFbSqJTbsZgYEA%3D%3D" rel="nofollow">Javascript诞生记</a></li>
<li><a href="https://link.segmentfault.com/?enc=9dY%2FSWtlv1YLc02zA0PjLA%3D%3D.iP4yg0vQ0UmwdaTZWdgvreMj6aa95ovFhh7xX1bv2R6nHdHYDtD02tdwd6gq5WtU5l7Og%2FhW9aISGVV5OiNULgmy1OjVuU3WtqFk9MLoly4wDoTKvV7bNHoaymduDjw9" rel="nofollow">Is JavaScript a (true) OOP language?</a></li>
<li><a href="https://link.segmentfault.com/?enc=ajJTr5ycon1h87d8oKUHTg%3D%3D.xPhGxLXVugxpGzQNWMMFnaUbVOORORnwF3Rq17doWjsNRWQDdqYLYDPwliNzdnNq" rel="nofollow">First-class functions in Java 8</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2Fhyt%2Fk%2F9QkEn5PZVZ4Bd8A%3D%3D.8lWTv0amEq5LDsyKWmYFImsE77yFgPfAUgCmfwNAR7d91rw3wZqkyTIdMqFJez4L3vtBJMDutp0krF%2BWLdfXCFLB%2FBQPLj%2FulGKrTn0H9Tc%3D" rel="nofollow">《聊聊我的第一篇10万+,同时反驳某些评论》</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=tQUZBfOPu6qyhwt5X1SkwQ%3D%3D.txgvfK%2FlFhAYq50DJw1kCeXxiFlzIt3CRIzv6taMh%2BU%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=NhgZz3dNPOkD7Oojp60a0w%3D%3D.Bwih%2BRbtdW1%2F739C4teHhxTZD3FMGbl1Bcf%2BqeZ1H5aBecYxOlglxR%2BYL1C7MOXj" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=xoGFR6zFI16outQBo8BdEg%3D%3D.hoE%2FGFPAlvClPT7hTaGhYMPgBqaEKlUQQl4JQ9ZP9JI%3D" rel="nofollow"> Fundebug</a>以及本文地址:</p>
<p><a href="https://link.segmentfault.com/?enc=fq5MKT%2Fo%2FqvPvJXMBirsaQ%3D%3D.wypNmuB3QnT82t5s4dtDe%2FYFIVSSmGD6L3FrgIccpDPPkTtmZC7zRBxBtwHOcxgQH5vt5dyGBRvitg6dxnj8mGvYim6jsRubJ434IOQ39LE%3D" rel="nofollow">https://blog.fundebug.com/201...</a></p>
Fundebug前端JavaScript插件更新至1.8.2,修复2个小BUG
https://segmentfault.com/a/1190000019512956
2019-06-18T15:16:35+08:00
2019-06-18T15:16:35+08:00
Fundebug
https://segmentfault.com/u/fundebug
2
<p><strong>摘要:</strong> 修复2个BUG,请大家及时更新。</p>
<p><img src="/img/remote/1460000019373421?w=900&h=383" alt="" title=""></p>
<h3>Fundebug前端异常监控服务</h3>
<p><a href="https://link.segmentfault.com/?enc=brL5pFD8nnQzX1OlTq%2Fcow%3D%3D.46OeRcZCqKiDQjS5ILa6Ayp022RLH%2BpfRkzc6ad%2BRfg%3D" rel="nofollow">Fundebug</a>是专业的程序异常监控平台,我们JavaScript插件可以提供全方位的异常监控,可以帮助开发者第一时间定位各种前端异常,包括:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=qY7QY0NOmAI%2BdNSTvkQrsQ%3D%3D.%2FS18%2BUzngzzkjsuJwbE0aze2aIJ1F30l%2BoTeWxTmsOUd6iPZyj5lZKFdcFx7zbfds9PubaJGzsR1mUt6ShYNVf7vhIL2R82Fp6441ldzpxg%3D" rel="nofollow">JavaScript执行错误</a></li>
<li><a href="https://link.segmentfault.com/?enc=iC1Y3KgP1RIpQYCNSKSreA%3D%3D.3X%2B9zG%2B8fqgV5RWoHirnEKMJTW7HiuvQlN67LtbB7LePyKhVHrWvEeu7YPVTdtLlsbaAIfL%2BJO%2BgOZ2n2qt0OMF1W1BSo1lmO4xVtrSvQAM%3D" rel="nofollow">资源加载错误</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2BKDrJLhqOPto8EQpNs%2FLFg%3D%3D.yJgGUO50KIT31IOriG5T6b9EX9T%2F9J42ldcn%2FWTo%2FHqc4YriCJRi6OGrDw9Tf4cwQtRorsEfkYX4E1eHlCQbMg%3D%3D" rel="nofollow">HTTP请求错误</a></li>
<li><a href="https://link.segmentfault.com/?enc=SnridxKpcsPgBZ2Zvr9npw%3D%3D.GZr5quEhx7CzHr3YxUBthohyd6QC3mHwUiGiQcOmPt%2FH5N1%2FkCZ3DqE2ScWYh4qNXeRDXEef%2BaqrFx2inpMWkLrC603IG4auS5m1BSaONEU%3D" rel="nofollow">unhandledrejection</a></li>
<li><a href="https://link.segmentfault.com/?enc=O5%2FeNFw%2FZBYqckUlriuvuw%3D%3D.%2BUazo4q6sVgNPbzILJrINrX%2FgyDQEEbfFkG4A4JbsuUIcUbGGDjjp2M7Fc%2BBs8SOz3%2BqU56Is3yzPn6kgRggS9CdJjJoo4kljj0dINTnIZY%3D" rel="nofollow">WebSockect连接错误</a></li>
</ul>
<p>并且,我们可以记录用户行为、“录制”用户操作视频,帮助开发者快速复现BUG,提高Debug效率。</p>
<p>Fundebug前端异常监控插件更新至1.8.2,修复了2个小BUG:</p>
<ul>
<li>修复用户行为中重复记录HTTP请求的BUG</li>
<li>修复Websocket的onerror为undefined报错的BUG</li>
</ul>
<p>这2个BUG都不会影响Fundebug功能,不过为了避免造成困扰,请大家及时更新插件。</p>
<h3>修复用户行为中重复记录HTTP请求的BUG</h3>
<p>根据用户反馈,Fundebug插件有时会在<a href="https://link.segmentfault.com/?enc=1F9b1A6vt7GUPyAgOrAMDA%3D%3D.XQv%2F4tNM1r%2FgK4hxm3EAguSpEg92yFacvqnx%2Bx%2BJ9OM73wX1E7EtkAFaoBt59oO%2B%2B5BKGQaqdhE9Q4lwEHFOq52m6I8oSUF%2F5Mf7e33bb3I%3D" rel="nofollow">用户行为</a>中某些HTTP请求:</p>
<p><img src="/img/remote/1460000019512959?w=687&h=591" alt="" title=""></p>
<p>这个问题的根本原因应该是<a href="https://link.segmentfault.com/?enc=2p5HUjpDfSUigabhmOsmVA%3D%3D.MV%2B%2FjG6IoMqr7qGb4pZov9pT6fWqjbU8SoDwDDajwbd43kd3JC4ukckBuVhlMTT5wJalN5wrc3hRa%2BNHESsSNw%3D%3D" rel="nofollow">浏览器的BUG</a>导致的,我们通过对插件代码进行修改规避了这个问题。</p>
<p>这个BUG不会影响Fundebug的功能,不过为了避免造成困扰,请大家及时更新插件。</p>
<h3>修复Websocket的onerror为undefined报错的BUG</h3>
<p>根据用户反馈,当我们将Websocket的onerror设为undefined时,会导致Fundebug插件报错:</p>
<pre><code class="javascript">var ws = new WebSocket("wss://ap.fundebug.com/api/events/count");
ws.onerror = undefined;</code></pre>
<p>报错信息为:”TypeError: null is not an object (evaluating 'n.apply')“。我们优化了监控WebSocket连接错误的代码,可以避免这个报错。</p>
<p>这个BUG不会影响Fundebug的功能,不过为了避免造成困扰,请大家及时更新插件。</p>
<p>最后,感谢Fundebug用户<strong>暗元素</strong>的反馈与协助。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=iz5Us9nN3FBL3oLBO5%2BvFw%3D%3D.PhEJOwQACdwteUBYAXKjsE2FmvCQxq4gmSrW9TpZO0h2s4E86ZXz1NXT4SjWF60VKFbLm9pPJ8EoinTGX7Ng8Q%3D%3D" rel="nofollow">Fundebug前端JavaScript插件更新至1.2.0,支持监控WebSocket连接错误</a></li>
<li><a href="https://link.segmentfault.com/?enc=UzsyVLrj%2B%2FrxKurdxNs1yg%3D%3D.ecRqdMNUrLQsvp3CSin9HXwfuUhvtAYxFHdLybXLutKrjZmZwCmrMULOZzyXgARwO8813j4bVBWk9pITJujnSwKg8ogOT42o49dTG8E7IeI%3D" rel="nofollow">没有Fundebug不能复现的BUG</a></li>
<li><a href="https://link.segmentfault.com/?enc=eGUxn%2FC8sJLcwL6snuFU4Q%3D%3D.SWymfoPwEeZVSUrD81J8O8JQk73T24ImmhpJ06GbYfzYAlzyGNgAnWCMbr768PnHKS0csBdbW509RW%2F3DwJZxUn41w0vkvJB5VTCCfDpv%2FU%3D" rel="nofollow">Fundebug录屏插件更新至0.4.0,修复BUG,优化性能</a></li>
<li><a href="https://link.segmentfault.com/?enc=0GN87vrBULATdwWBgpZBCQ%3D%3D.IF4nIlvhKWfkThs9ylKtJmuBxwResOspseUVI6cOfebpUVm%2B5xqv0%2BzTJJPl9MzI7T44gqYuasgQdUWdg18rGw%3D%3D" rel="nofollow">Fundebug文档 - JavaScript插件版本</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=l2oObwHDa57kPygvrzAR6g%3D%3D.7WqvXVKZRvh0%2BgA%2FYkcwme3JUVfg9MZD2Iaz1omqn5A%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多知名企业。欢迎大家<a href="https://link.segmentfault.com/?enc=rNHvf9GK3XdvXBKQjn%2BTvg%3D%3D.9ZU7KLAjbWQQBxrYYX59Psbpm8ENXgAuanl6w8gWe6InTxrCZaazmNHdQjNCakRd" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=KQzuOVDKtNqEbmNS9oNWyQ%3D%3D.Q3utasAdJ7fYFbHnCggeh8IlK3wPb91HSEJrqTKGkgw%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=2ydyxAGYX4r3uQL3%2Bukhlw%3D%3D.KNv2qE%2F%2BO5AbDqlMpihLAXZIZyWjxbIfcaQyaRmeT5VIEGzw1T6clJgvTgLeA22qU3kG9O4zcUtx8mWkcR4hlA%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/06/18/fundebug-javascript-1-8-2/</a></p>
JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
https://segmentfault.com/a/1190000019507756
2019-06-18T09:07:42+08:00
2019-06-18T09:07:42+08:00
Fundebug
https://segmentfault.com/u/fundebug
11
<p><strong>《JavaScript 深入浅出》系列</strong>:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=Kdv4ILMNzDfvJiDrn%2Fqy8w%3D%3D.c%2BuZaxVmNtMcjXxj29EJuOgqtpu3%2FoxzU%2BfDacKhugVHCdmt8gFz3r7iGkRAjOATzRYqbGqX8A6Voohf0F6dpg%3D%3D" rel="nofollow">JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼?</a></li>
<li><a href="https://link.segmentfault.com/?enc=0ARu%2B%2BuERCLpGosKLxiqKA%3D%3D.Qt7nAQMq4%2FRMZFJoSzJwpwP9KWNhlM1PtfJXg95pa7gCN6fz1xzFXDsSYF6eytySMIrxmUSpdHS478iaXDyMXksIPKXySkDSRt4dtMbDtWU%3D" rel="nofollow">JavaScript 深入浅出第 2 课:函数是一等公民是什么意思呢?</a></li>
</ul>
<h3>普通函数与箭头函数</h3>
<p><strong><a href="https://link.segmentfault.com/?enc=CG6Rxyz6s0cG9YV6f6rnmQ%3D%3D.bMVCL53wv1NomXcQeWs9IYs8qWVbWbR7mHMdUGW0ST%2BOw1%2F5T2Qnh%2BWgKuGHYZrgc%2B%2BG1srkm5WDCcwHf6ALGIzaY8UY145%2FObgdmK6IrKUU9UbOtwmRi0Ab%2BOy%2FtHUE" rel="nofollow">普通函数</a>指的是用function定义的函数:</strong></p>
<pre><code class="javascript">var hello = function () {
console.log("Hello, Fundebug!");
}</code></pre>
<p><strong><a href="https://link.segmentfault.com/?enc=%2Fe8ibfOCBza0c%2FB5tUeZDA%3D%3D.Sa4vzPVTWw6swCsLJDkV4X%2Fu8Y3mDdOVqQk1alARiZ68fAvLWHPqVWzRKl6Kn%2B%2FrK1yYZbURtUnXVoT4NLuDQai443%2BmOd3UFM0FwQ2KTeYH15CMhot3VzBAUXQ0HPAz" rel="nofollow">箭头函数</a>指的是用=>定义的函数:</strong></p>
<pre><code class="javascript">var hello = () => {
console.log("Hello, Fundebug!");
}</code></pre>
<p>JavaScript箭头函数与普通函数不只是写法上的区别,它们还有一些微妙的不同点,其中一个不同点就是this。</p>
<blockquote>箭头函数没有自己的this值,箭头函数中所使用的this来自于函数作用域链。</blockquote>
<p>这句话很简单,不过听着稍微有点莫名其妙,得从头说起。</p>
<h3>this到底是什么?</h3>
<p>关于this的文章也够多了,有时候越描越黑,我就不再添乱了,我只负责搬运一下MDN文档:<a href="https://link.segmentfault.com/?enc=1Kce2OAjOEw6B7qB0HLMCQ%3D%3D.mrwStzlb%2FhxWeKa3fPGArmXSrtMcwOcnjapSWPnzcUW%2FPdoFIVGPTUQVU1G5JlOCxi1qL5UK2ciF1eH0ymxuuI%2BIs9r6PuhOwmfRfm4XZJwDR0aJbmwI9%2FoL%2BTfQE28W" rel="nofollow">this</a>,感兴趣的可以仔细阅读一下,我摘录一些最重要的话就好了。</p>
<blockquote>A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.</blockquote>
<p>JavaScript是一门比较奇特的语言,它的this与其他语言不一样,并且它的取值还取决于代码是否为严格模式("use strict")。</p>
<p><strong>this的值是什么?</strong></p>
<blockquote>The JavaScript context object in which the current code is executing.</blockquote>
<p>this就是代码执行时当前的context object。</p>
<p><strong>Global context</strong></p>
<blockquote>In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.</blockquote>
<p>代码没有在任何函数中执行,而是在全局作用域中执行时,this的值就是global对象,对于浏览器来说,this就是window。</p>
<p>这一条规则还是比较容易接受的。</p>
<p><strong>Function context</strong></p>
<blockquote>Inside a function, the value of this depends on how the function is called.</blockquote>
<p>函数中的this值取决于这个函数是怎样被调用的,这一条规则就有点变态了,也是很容易出BUG的地方。</p>
<p>另外,this的值还与函数是否为严格模式("use strict")有关,这就非常的丧心病狂了...</p>
<p>大家如果好奇的话,出门左转看MDN文档,我多说无益,只说明一种简单的情况。</p>
<p><strong>As an object method</strong></p>
<blockquote>When a function is called as a method of an object, its this is set to the object the method is called on.</blockquote>
<p>当函数作为对象的方法被调用时,它的this值就是该对象。</p>
<pre><code class="javascript">var circle = {
radius: 10,
getRadius() {
console.log(this.radius);
}
};
circle.getRadius(); // 打印 10</code></pre>
<h3>self = this?</h3>
<p>当我们需要在对象方法中嵌套一个内层函数时,this就会给我们带来实际的困扰了,大家应该写过这样的代码:</p>
<pre><code class="javascript">// 使用临时变量self
var circle = {
radius: 10,
outerDiameter() {
var self = this;
var innerDiameter = function() {
console.log(2 * self.radius);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印20</code></pre>
<p>outerDiameter函数是circle对象的方法,因此其this值就是circle对象。</p>
<p>那我们直接写<code>this.radius</code>多好啊,可惜不能这么写,因为内层函数innerDiameter并不会继承外层函数outerDiameter的this值。outerDiameter函数的this值就是circle对象,this.radius等于10。</p>
<p>但是,<strong>innerDiameter函数的this值不是circle对象</strong>,那它到底是啥?它是innerDiameter函数执行时当前的context object,这个context object又是啥?其实我也晕了,所以不妨测试一下:</p>
<pre><code class="javascript">// innerDiameter函数中的this是window
var circle = {
radius: 10,
outerDiameter() {
var innerDiameter = function() {
console.log(this === window);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印true</code></pre>
<p>innerDiameter函数中的this是window,为啥是window这个不去管它,反正不是circle对象。</p>
<p>因此,如果我们直接在innerDiameter函数中使用this的话,就出问题了:</p>
<pre><code class="javascript">// 使用普通函数
var circle = {
radius: 10,
outerDiameter() {
var innerDiameter = function() {
console.log(2 * this.radius);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印NaN</code></pre>
<p>于是,我们不得不使用一个临时变量self将外层函数outerDiameter的this值搬运到内层函数innerDiameter。</p>
<h3>.bind(this)</h3>
<p>我们也可以使用<code>.bind(this)</code>来规避this变来变去的问题:</p>
<pre><code class="javascript">// 使用.bind(this)
var circle = {
radius: 10,
outerDiameter() {
var innerDiameter = function() {
console.log(2 * this.radius);
};
innerDiameter = innerDiameter.bind(this);
innerDiameter();
}
};
circle.outerDiameter(); // 打印20</code></pre>
<p>但是,无论是使用临时变量self,还是使用.bind(this),都不是什么很简洁的方式。</p>
<p>总之,普通函数的this取值多少有点奇怪,尤其当我们采用面向对象的方式编程时,很多时候都需要用到this,大多数时候我们都不会去使用.bind(this),而是使用临时变量self或者that来搬运this的取值,写起来当然不是很爽,而且一不小心就会写出BUG来。</p>
<p>正如<a href="https://link.segmentfault.com/?enc=oBPV%2BOMy%2Fewwm9wOTRCDcw%3D%3D.fb0gP0LKLG0m%2F%2Bz9RzMtUU93c%2BOJTKKq3BJRkNxgNMHQJvaZJCRMRA%2BSW8DzFJnHt2uFIV3MTnQIxTheU9zCixvuQ2cmwTHP0NXku8z6HPdNWlk8Opz9Wm%2BKXncTVWj2i1CaIdauirZbLkJFaHONnw%3D%3D" rel="nofollow">MDN文档</a>所说:</p>
<blockquote>Until arrow functions, every new function defined its own this value based on how the function was called。This proved to be less than ideal with an object-oriented style of programming.</blockquote>
<h3>箭头函数</h3>
<p>箭头函数的this取值,规则非常简单,因为this在箭头函数中,可以看做一个普通变量。</p>
<blockquote>An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules.</blockquote>
<p>箭头函数没有自己的this值,箭头函数中所使用的this都是来自函数作用域链,它的取值遵循普通普通变量一样的规则,在函数作用域链中一层一层往上找。</p>
<p>有了箭头函数,我只要遵守下面的规则,this的问题就可以基本上不用管了:</p>
<ul>
<li>对于需要使用<code>object.method()</code>方式调用的函数,使用普通函数定义,不要使用箭头函数。对象方法中所使用的this值有确定的含义,指的就是object本身。</li>
<li>其他情况下,全部使用箭头函数。</li>
</ul>
<pre><code class="javascript">// 使用箭头函数
var circle = {
radius: 10,
outerDiameter() {
var innerDiameter = () => {
console.log(2 * this.radius);
};
innerDiameter();
}
};
circle.outerDiameter(); // 打印20</code></pre>
<p>对于内层函数innerDiameter,它本身并没有this值,其使用的this来自作用域链,来自更高层函数的作用域。innerDiameter的外层函数outerDiameter是普通函数,它是有this值的,它的this值就是circle对象。因此,innerDiameter函数中所使用的this来自outerDiameter函数,其值为circle对象。</p>
<h3>结论</h3>
<p>JavaScript是Brendan Eich花了10天时间设计出来的,因此各种莫名其妙的特性,this也算是其中一个奇葩。好在这些年ECMAScript标准发展很快也很稳定,每年撸一个新的标准,多少可以弥补一下JS的先天不足。</p>
<p>箭头函数对于this取值规则的简化,其实也就是为了少给大家添乱,谁能记得住普通函数this取值的那么多条条框框啊。。。</p>
<p>另外,MDN文档绝对是一个宝藏,大家可以多看看。</p>
<p>关于JS,我打算开始写一个系列的博客,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。也大家欢迎添加我的个人微信(KiwenLau),我是<a href="https://link.segmentfault.com/?enc=TIq6CWzhb9whAoW4fN%2FIKw%3D%3D.upYotgAKKV0lx%2BpJ9LScSlTka5%2FD%2BjQaG0jBrvJqrCM%3D" rel="nofollow">Fundebug</a>的技术负责人,一个对JS又爱又恨的程序员。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=EdIBJGeRgsLv5kGE7qPrJg%3D%3D.gCylYx9e8eNWVYgxULZpscmTUKbZuOZEJz7CAyMDybIZxrUcGw0WSsLSKcxzf2%2BUUGztLp9%2FtO6wKkgVguYFDw%3D%3D" rel="nofollow">ES6 In Depth: Arrow functions</a></li>
<li><a href="https://link.segmentfault.com/?enc=CRSmumgVuobKEVKNv3px5g%3D%3D.iM1wLmchqwFRJUz3Cux08fQWLRYZeRK8dR8AW7br%2BOGdsjMqUMYm51qlPyypmepsYfYAhzC%2B7NSwyxivXudlNFPCQRlXMJbfSVm3CIAQNyPgKwhJ6iXRMbdDjRHi5%2BwSC4CtNuun8jz%2FVO2d0EQ30A%3D%3D" rel="nofollow">MDN文档 - this</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=GspzRyuczDUsDAs77m%2FgRA%3D%3D.CulHYcgdSc8DisTMAjZ4G4vCv5mPhINAskTk6Ot3KpA%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=Jb0gJBeizFWWC9NPOn8BgA%3D%3D.f%2BsrRptFINyhE1ha836mU0RZRsQe%2BDInco3420eJs9oGvt6Mde97sI22ABOeQHlD" rel="nofollow">免费试用</a>!</p>
<p><a href="https://link.segmentfault.com/?enc=GBOJP6MVxSsqHjp46b5j4A%3D%3D.ke2LDN9oub0iCCLX1xvqa55jfkBi5na4iNSUPyHa84RzltPZGc5DiFaHGWf6ZGgH" rel="nofollow"><img src="/img/remote/1460000016902244?w=400&h=225" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=ztLuCl4JYuzIzbmpekeByg%3D%3D.Y7gYiFXnjZY2BHzpenFvQ1C9gufYf2Oql8eKApzVniM%3D" rel="nofollow"> Fundebug</a>以及本文地址:<a href="https://link.segmentfault.com/?enc=mkC%2FezJQ1h75b7FNYnoP0g%3D%3D.rm%2Bv5BaOEKAxdCyTkikEjLQe6zr0xdFk7VIo4CNI32ZmHYGI3vitei4JLr9biq8ttN6ppoAQVrNvDQfnaXGhzw%3D%3D" rel="nofollow">https://blog.fundebug.com/201...</a></p>
Fundebug 微信小程序BUG 监控插件更新至 1.3.1,支持监控 HTTP 慢请求
https://segmentfault.com/a/1190000019458993
2019-06-12T17:15:52+08:00
2019-06-12T17:15:52+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> <strong>1.3.1</strong>新增 httpTimeout 配置选项,支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG。</p>
<p><img src="/img/remote/1460000018947435?w=900&h=383" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=mwy5VCjVI%2B34LM%2FakgVLNA%3D%3D.L6cxbWyQ81XSTlqUf14aWQuXQAGdC5VdRozd8BW2gkE%3D" rel="nofollow">Fundebug</a>是专业微信小程序 BUG 监控服务,可以第一时间捕获线上环境中小程序的异常、错误或者 BUG,及时给开发者推送报警,帮助您快速修复 BUG。</p>
<p><a href="https://link.segmentfault.com/?enc=OAWvGFtv7qb8xubuFKYoLw%3D%3D.ynC7Z509Nl26NANDE%2FzTwe73AEzoUCXliUV3ufPrZ4A%3D" rel="nofollow">Fundebug</a>的微信小程序BUG监控插件更新至<strong>1.3.1</strong>,新增<a href="https://link.segmentfault.com/?enc=cZv4AcPyyRWHZpjhVKkqnw%3D%3D.OM38m4EDKOqx%2FKAcBAoN9htqPK4xW56ng7JSneLRbDMHg8g7atlxld3%2BZcqgsbgHcN6WFJDVNZ7wSGtTMhDx%2B1tIM6RqUqtXCEGUazXeBqQ%3D" rel="nofollow">httpTimeout</a>配置选项,支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG,请大家及时更新!</p>
<h3>监控 HTTP 慢请求</h3>
<p>Fundebug 专注于 BUG 监控,暂时无意于提供全面的性能监控服务。但是,当 HTTP 请求过慢,导致用户体验很糟糕时,也可以理解为一种广义的 BUG。HTTP 请求的性能问题,可能是代码的算法不够好导致的,有可能是数据库的索引不合理导致的,还有可能是其他原因,这些都是技术层面的”BUG“,需要开发者及时处理。</p>
<p>当然,监控所有 HTTP 请求的响应时间不是我们 Fundebug 需要做的事情,因此我们只支持监控慢请求。用户只需要配置一个阈值<a href="https://link.segmentfault.com/?enc=NdIqhfu9zs8btH4%2BrGCHnA%3D%3D.jXpEsVoYPyeN2S1gMF65uE2dI%2Fm463hnKwpPgQy%2FDkFhweWxaf%2FQ%2FpN23ku%2FvT8vBUsXcax7Dy7YO78szR7paRDSCPhSojbZaTLDSdGfxJk%3D" rel="nofollow">httpTimeout</a>,所有响应时间超过阈值的 HTTP 请求都会上报的 Fundebug,这样可以帮助开发者发现一些慢请求,及时优化性能。</p>
<h3>微信小程序配置选项 networktimeout</h3>
<p>根据微信小程序的开发文档,<a href="https://link.segmentfault.com/?enc=CCeav4bM0SRj8JveAvigyg%3D%3D.cgs1WkgSLeaj8ZDdWRbn1aDwNAc66vHXKTiac%2FsMCcwcDPxViRfMUcBCMAnYTscF8IjFht88K1cIYcW96sVt0zYNL1n62rPfvvBUK47vwvw%3D" rel="nofollow">网络请求</a>的默认超时时间是 60s,用户可以通过配置<a href="https://link.segmentfault.com/?enc=FgVqPLI4cXxeliGssmjHpw%3D%3D.SmGWDBxqPThC9PuTR%2FVD2XJb8qo058OaNsBynKnUEVGLII9Ez4ZuUUzrRm6YLS9h6Xgs0Iiiy6uRx0Q0xKBLhy5CsYYBP0XWua7nrGNGC8o%3D" rel="nofollow">networktimeout</a>来自定义。如果某个 HTTP 请求的响应时间超过这个阈值的话,则该请求会出错,Fundebug 也会上报这个超时错误。但是,networktimeout 不能配置的太低,否则超时的请求都会失败,这并不合理。所以配置 networktimeout 并不能实现监控 HTTP 慢请求的目的。</p>
<h3>httpTimeout</h3>
<p>监控 HTTP 慢请求的正确方式是通过 Fundebug 的配置选项<a href="https://link.segmentfault.com/?enc=dKMBzi6LRUlZYFeND0A9BA%3D%3D.9E7p%2F%2FRxzkSv%2FsvovTvzAauJpiF5lQlCTrcrNfH9FOYznwnE%2Bh6inCzrgA6%2FgIMBZD6bhH0huLY90Yd4qvm%2BYbAeL1GPyiI6BIMSdI9efIY%3D" rel="nofollow">httpTimeout</a>来实现。</p>
<p>httpTimeout 类型为 Number,单位为毫秒(ms)。</p>
<p>如果你希望监控较慢的 HTTP 请求,则可以通过<a href="https://link.segmentfault.com/?enc=3xwkXgM2HMrKfKSq0EgUaw%3D%3D.rsdDJCwb5CLadHNFKgL24jix6cDqAAcZz%2Bdrvlw4Um4Ld7RJgJzl%2FYhx7kRME94lWFYzrDB%2FMeQITCYPNY05zmJXL9YPitK4N6%2F6qYzjq2s%3D" rel="nofollow">httpTimeout</a>配置阈值,比如 1000:</p>
<pre><code class="js">fundebug.init({
httpTimeout: 1000
});</code></pre>
<p>则所有响应时间超过 1000ms 的请求都会上报到 Fundebug。</p>
<p>最后,感谢 Fundebug 用户<strong>爱享到</strong>与<strong>阿苏</strong>的反馈。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=dYmcMZw8lHBoR78FFmpIfg%3D%3D.fKIj0PZwSUbHPqAkvgX1U5J%2BScILDsiSSd%2FkNRRe7XO1VjtxSC0SXb8%2F0XAFnedlGKbh%2FVEfxmzg%2FDHCVzXpsVmTFnFyYXprMub6D8YWowU%3D" rel="nofollow">Fundebug 文档 - httpTimeout</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=SOSYNH2wmYHisjZzdZ8WnQ%3D%3D.nDwBgIVJeQXkMZkrRC9XyKzwWGkYplkA9znTTkIOqMg%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=UiNYb2imGI9NuHj31a%2FHHA%3D%3D.f8OfiRwwLli6cQ2xSILmQR%2Ba4mU4Wukj11or7Idc5cNZVaUACkZA01gVz5vYLo56" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=unmxojoKnbCEX3n3H2i7yA%3D%3D.gEsBEo%2FTiPIan2Grl7%2BeOJMgy%2FQoHKp%2FtcFkt15%2FHJI%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=zKSZAot20gB4btYmesqb7g%3D%3D.umjDFzJvxeHM7hzGJpy2GVpt%2Fwd2qBC06KFfiKD2L0tFCo33P4gYK%2BxDjUmSnBBKJyx6l0J%2FekuUfQ9s4qbyQkgZv1%2F%2Fdzjd895gdag8TBU%3D" rel="nofollow">https://blog.fundebug.com/2019/06/12/fundebug-wechat-miniprogram-1-3-1/</a></p>
Fundebug前端JavaScript插件更新至1.8.0,兼容低版本的Android浏览器
https://segmentfault.com/a/1190000019373418
2019-06-03T15:35:16+08:00
2019-06-03T15:35:16+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 兼容低版本Android浏览器,请大家及时更新。</p>
<p><img src="/img/remote/1460000019373421?w=900&h=383" alt="" title=""></p>
<h3>Fundebug前端BUG监控服务</h3>
<p><a href="https://link.segmentfault.com/?enc=es7dB3DqQYS3rulCudx%2F4A%3D%3D.g0SmirUeUkVdrQwcqIQEEI5oEP8KaP1cBrvM1%2FNoYmU%3D" rel="nofollow">Fundebug</a>是专业的程序BUG监控平台,我们JavaScript插件可以提供全方位的BUG监控,可以帮助开发者第一时间定位JavaScript执行错误、HTTP请求错误以及资源加载错误。并且,我们可以记录用户行为、“录制”用户操作视频,帮助开发者快速复现BUG,提高Debug效率。</p>
<h3>1.8.0兼容低版本Android浏览器</h3>
<p>用户和我们反馈,Fundebug在Android 4.4与 5.1.1浏览器上会报错,我们在1.8.0修复了这个问题,请大家及时更新插件。</p>
<p>通过优化Babel配置,我们兼容了一些低版本的浏览器:</p>
<pre><code class="javascript">{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"ie": 6,
"android": 4,
"ios": 8
}
}
]
]
}</code></pre>
<p>可知,Fundebug插件最低兼容IE 6,Android 4以及iOS 8。注意,我们保证Fundebug插件在这些浏览器下不会出错,但是并无意于为低版本浏览器提供全面的BUG监控服务。例如,我们的录屏功能仅支持一些高版本的浏览器,IE 6 ~ IE 10均不支持。</p>
<p>最后,感谢Fundebug用户<strong>闁鑅</strong>与<strong>疯狂紫萧</strong>的反馈。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=aj5%2FPHj6rF%2B9VfWevQ90ZA%3D%3D.3WyMhykeqlv2oINB0dWUiiOdsYETMDhDlZh61pu7%2FCjVxg9zKH0GwVe2Lc8ibjhQn4yU4Zxyj%2FZ83xsd2gPzyFpF14PR%2FIsjfA7aYdNfEdI%3D" rel="nofollow">Fundebug录屏插件更新至0.4.0,修复BUG,优化性能</a></li>
<li><a href="https://link.segmentfault.com/?enc=No0S2JkqTMj%2FgLgofNS7hg%3D%3D.f8ecC7Y4uy7y1BoRa%2FbD%2FjadCoEvFnoWOQCNk3O94gKZAvuNaKO%2FD7V%2B75awBbTN%2FVoA3H1equ8Ceay%2FTtnvxA%3D%3D" rel="nofollow">Fundebug文档 - JavaScript插件版本</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=rL5GcEYXd9RHFaTaUjPSug%3D%3D.ikFrnWrlIvrPCota6wZt1jfUAicXERT53otN8aRFZK0%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=txLgJQMcP1cOrpQbQPmyEw%3D%3D.x8QjvlgPpa3TF0u3wC%2FEhTaTWHjNMBtqbND89np7AESfEm4aL0mfGv8EEb6Z0Zc%2B" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=Qn6vyBQinBSHerP5zspVFQ%3D%3D.hOmM39%2FdIZ5f8T4JQfOx%2F72z9aYp3k%2Fe8Lv%2BWOF%2BRRk%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=N0RK6u6w1rAzTQeA09%2B8Xw%3D%3D.6FR9%2F6%2B5hXyQYk5Cwxq0U5cXQW%2BNX2T2HunXufci7U7ECwcVAPa4MbkhWgqaNtxeYYsl4AwLs%2BlWle2SE18ttQ%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/06/03/fundebug-javascript-1-8-0/</a></p>
Fundebug录屏插件更新至0.4.0,修复BUG,优化性能
https://segmentfault.com/a/1190000019302052
2019-05-27T10:36:41+08:00
2019-05-27T10:36:41+08:00
Fundebug
https://segmentfault.com/u/fundebug
6
<p><strong>摘要:</strong> 录屏功能更加强大,欢迎免费试用!</p>
<p><img src="/img/remote/1460000019302055?w=900&h=383" alt="" title=""></p>
<h3>关于Fundebug录屏功能</h3>
<p><a href="https://link.segmentfault.com/?enc=Tb881d6Mvoz%2B0NpBgILKdQ%3D%3D.gZInlVEmOPkrVfB10dPqf0b%2Fv33Ti7K%2BOXZ%2BuTVduA0%3D" rel="nofollow">Fundebug</a>是专业的程序BUG监控服务,当线上应用出现BUG的时候,我们可以第一时间报警,帮助开发者及时发现BUG,提高Debug效率。</p>
<p>在网页端,我们通过原创的录屏技术,可以100%还原BUG出现之前用户的操作流程,帮助开发者快速复现出错场景。请查看演示视频:<a href="https://link.segmentfault.com/?enc=fUhbgwtflyTaW%2FdI0lZs2A%3D%3D.WRak0RRUWanUgo%2F5s%2BtXDvKBT%2Fx8HhNneqFhZ9VeGWQcd3%2FTFEELm57RFGNQwWLR" rel="nofollow">演示视频</a></p>
<p>其实,我们录制的并不是一个真正的视频!算法经过优化,整个“录制”过程 CPU 的使用率非常低。和传统的视频相比,体积小了成百上千倍。Fundebug 插件“录制”的“短视频”,压缩后的体积只有几十 KB。</p>
<p>感兴趣的话,欢迎大家<a href="https://link.segmentfault.com/?enc=EOs7i6cu5GqyY%2FwCqnCpnw%3D%3D.1PAn42sqQZxi5q2iD%2FiFVHzSlpkDZ6nJGch5UWtdzY20sUKyAjVcep8j4FjJBppr" rel="nofollow">免费试用</a>~</p>
<h3>尊重用户隐私</h3>
<p>录屏功能涉及到用户隐私,我们作为第三方服务,也非常重视这一点:</p>
<ul>
<li>Fundebug默认关闭录屏功能,开发者需要的时候可以自行开启;</li>
<li>Fundebug并不是全程录屏,只会录制BUG出现之前10~20s的用户操作;</li>
<li>Fundebug提供<a href="https://link.segmentfault.com/?enc=yw8odRHMdmnFzw3DFDHt5Q%3D%3D.3MR6X8C75ZUthK9AIa5QSCDscGfFhr%2BCpZ6pMRKRnyTJ%2Bx8RcBvUJ4zGvfB2qQ5bBhVwO8tgApdSWKCosThcvw%3D%3D" rel="nofollow">敏感信息过滤</a>过滤功能,开发者可以过滤掉用户隐私信息;</li>
<li>Fundebug重视数据安全,传输过程全程加密,<a href="https://link.segmentfault.com/?enc=DiafBxnRkRGRv7zUuDnr4w%3D%3D.%2FNZ%2BL19UCRIZmHDpUBWEogf%2BHzKFSncLdwYNBeGjSODe6giQzh9qyRMRfeDgWqs%2FJV0kIjH9%2F5F4rIiAEC7qFQ%3D%3D" rel="nofollow">数据库有多重安全防护</a>;</li>
<li>Fundebug会定期(目前是删除60天之前的数据)删除过期错误数据,这样既节省成本,也保护用户隐私;</li>
</ul>
<p>请大家放心使用~</p>
<h3>录屏插件更新至0.4.0</h3>
<p>此次更新对插件做了多方面的升级,主要包含 BUG 修复和性能优化两个方面。</p>
<p><strong>BUG 修复</strong></p>
<p>我们主要修复了以下3个BUG。</p>
<ul>
<li>静态资源重复加载</li>
<li>Safari 浏览器和 <a href="https://link.segmentfault.com/?enc=F3APQ%2FbWl4ABOZnLXHUlrQ%3D%3D.0%2FDvvL%2BbP%2BgwOwjZi53XUwyVVL23jZ%2Botq49FGCinO8FnndKBpfvRHKwZCp13%2BBf0mNAclkplZWVFxxZIvWziA%3D%3D" rel="nofollow">WKWebView</a>无法录屏</li>
<li>动态加载录屏插件失效</li>
</ul>
<p><strong>性能优化</strong></p>
<p>通过优化数据记录方式,进一步提升插件性能,并减少传输的数据量。</p>
<h3>接入方法</h3>
<p>从BUG 监控插件 1.7.3<a href="https://link.segmentfault.com/?enc=r%2BKCmmAIR2x4EUr2HRXZSQ%3D%3D.uvnaCQ25tc25ru0Eihlzn2nJcBP9T7aZ7uj9OrANZLcxUNYRTT%2FC8pRQNE9fVRiL26UIi%2BEL858Pdfs%2B1j7zgw%3D%3D" rel="nofollow">版本</a>开始,我们拆分了录屏代码。如果需要使用录屏功能的话,需要单独接入录屏插件。</p>
<ul>
<li>
<p>使用 Script 方式接入</p>
<pre><code class="html"><script
type="text/javascript"
src="https://js.fundebug.cn/fundebug.revideo.0.4.0.min.js"
/></code></pre>
</li>
<li>
<p>使用 NPM 接入</p>
<pre><code class="js">require("fundebug-revideo");</code></pre>
</li>
</ul>
<p>最后,感谢各位 Fundebug 用户的反馈。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=bnPuDmCs8LuIvcmdqSLFOA%3D%3D.BngoiGIfsBNGvD1xvzwfF2%2BJY1qZk2vu8r1zHDA8RvyoVkVGM478keo%2FEXelyUoWhN%2BFUcZSs%2BPT0hbB2qyJU%2BOSvT%2BH1mDjwfhmvvJ8i%2FA%3D" rel="nofollow">黑科技!Fundebug支持可视化重现出错场景</a></li>
<li><a href="https://link.segmentfault.com/?enc=vRODO2wTWHQUm4OzrvuDPQ%3D%3D.kCoLNBxYYFqmzbT94Gd9gVD1e%2BxJ%2B2TUMEXGe5%2Bf10X%2BTaOZ0FpNs9PqJTUZ%2B86MlGl6fO5KUq80wlakOYzi4w%3D%3D" rel="nofollow">Fundebug文档 - 录屏</a></li>
<li><a href="https://link.segmentfault.com/?enc=QrsNp53lqAfX%2F%2FQkj1kd9g%3D%3D.pMLKv%2Bi4W0a6oeYNAXH3q8DdaHMJck9w1ZLqKNumscf4RJInpDE3q%2B5JCSLYzq%2FJTEuajZaiz2r3KpB3ptDW1Q%3D%3D" rel="nofollow">Fundebug文档 - 敏感信息过滤</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=6BhMDGwiJfY1aZiHfYoRWw%3D%3D.lFr12DHtAWCA1nesRbrunicpO6JviMcCWPbsWZvYQgE%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=vyeMUxIz9Zb0%2BbXQ8A1jMA%3D%3D.YzW6Apji0IulY16BKfM5Uanb6rSavuZsOO%2FvL9FH3Cy0jtaS%2FMRm%2BpaNQQyeDs0%2F" rel="nofollow">免费试用</a>!</p>
<p><a href="https://link.segmentfault.com/?enc=spQVB6B6ibcA30P9KgaT5g%3D%3D.zVNg1aUy%2F%2BU5AUlYa6hqDcn3WgmilryWxfAcxLWBMr9yRYLkkYQmS3nGir%2FvTznhR%2F8dDVyBXD9ZQHu5NCAVqzjXQzAtSlFHf4DfnbtrWiMXrV3%2F6yirg3O1uqDW0b69" rel="nofollow"><img src="https://user-gold-cdn.xitu.io/2019/5/22/16add54d2024931c?w=560&h=315&f=png&s=158642" alt="img" title="img"></a></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=B7MLvHee6UZHGl5DGViFFA%3D%3D.dRgGULRqj2fLhA1wqOKMNCXk6fx8P2j%2Fp0Fn%2BKAc55w%3D" rel="nofollow"> Fundebug</a>以及本文地址:</p>
<p><a href="https://link.segmentfault.com/?enc=m%2BQxqA5%2F9OuGZnnbfaIODw%3D%3D.eIrf6e2CSlfp7N%2FiP59BlZSFe1E7uEhrmffFANlaDEoyVuR0MzXn1PZfb%2B0aDS9rmh2wITioF57rpEGSJZJSlxZujp1mPpbvlpcwXuPlUW0%3D" rel="nofollow">https://blog.fundebug.com/2019/05/26/fundebug-release-revideo-0-4-0/</a></p>
聊聊我的第一篇10万+,同时反驳某些评论
https://segmentfault.com/a/1190000019256107
2019-05-22T10:18:54+08:00
2019-05-22T10:18:54+08:00
Fundebug
https://segmentfault.com/u/fundebug
9
<p><img src="/img/remote/1460000019256110?w=900&h=383" alt="" title=""></p>
<p>元旦的时候,我立了一个Flag,今年要写一篇10万+,现在目标算是完成一半了。</p>
<h3>终于有了一篇10万+</h3>
<p>知乎后台显示我的回答《<a href="https://link.segmentfault.com/?enc=AjFvuCzVp5KnveMcmsXIWg%3D%3D.yay6TGbLrNmEGjeh%2F9VQYyiPDkRSbdYR0kuJm6ljCVjf54JYAPyvvtoKMu7aKhnQyGdH%2B9%2FoOJImQZpPfT%2Fm8A%3D%3D" rel="nofollow">如何衡量一个人的 JavaScript 水平?</a>》的阅读量已经超过了10万,具体截止2019年5月20号是<strong>115172</strong>。</p>
<p><img src="/img/remote/1460000019256111?w=775&h=632" alt="" title=""></p>
<p>阅读量已经超过10万了,为什么只是完成了一半呢?因为这篇博客其实是我翻译的,原文在Web Archive上能够找到:<a href="https://link.segmentfault.com/?enc=GAZczccd80VvpAmipFGJfQ%3D%3D.tPS0ilAb13no4kZSOyPCaTqCCpQ044lz8DX7uWE4whWRus3hL4%2FsC%2FWxixGMqUqNWPdHZviJ1xwCUM6l8cuYQOG05FdWLpn936S%2FvnCBHWRdoS%2FZmfaZraj5wl7dEuHLIcKv8RLKs9CZH7NY1udVmYs%2F06DL6VqLvZgZrjNyvAxHaYb7dAk3EyN2dGMScsjZpQqjlrwcEtk%2B3nejanfwQQ%3D%3D" rel="nofollow">10 JavaScript concepts every Node.js programmer must master</a>。而且,这篇博客是我2年前写的:<a href="https://link.segmentfault.com/?enc=o%2Bs9WNj63wQSungGE3QMwA%3D%3D.%2FqjtgBDTL0RAO2jdvZtln5WW4m%2FCH1HgqZ2p%2Fcx%2BwbPJ1QFV3bh90iuZ%2BBijDuuxd2F7aFIv6qLlp3SH74YF071yDLuH6yahUE1Cifa0aWc%3D" rel="nofollow">10个JavaScript难点</a>。不是原创,也不是今年写的,当然只能算是完成了一半。</p>
<p>虽然只是翻译,但是基本上等于"重写"了一遍,因为我翻译博客都是意译而非直译,这是为了保证可读性。中文和英文的写作套路完全不一样,英语喜欢用各种定语从句,强行直译的话读起来会非常莫名其妙。感兴趣的话,不妨对照原文和我的翻译看看。</p>
<p>刷知乎的时候,看到了这个问题:<a href="https://link.segmentfault.com/?enc=YverQNiPPzOxRXK2BDQsXQ%3D%3D.ekD1IUrrbV%2FwL7pARwOJCpwv1vQWbk5bT4w9qvcDyjY7v3Y1u%2FtciSGD0WnCdYX6" rel="nofollow">如何衡量一个人的 JavaScript 水平?</a>,就想起了自己2年前的博客,内容刚好合适,于是随手转发了一下。我对于这篇翻译的博客还是挺满意的,所以一直记得它,所以猜到它应该会比较受欢迎,后来发现它受欢迎的程度远远超过了我的想象。</p>
<h3>感谢知乎的推荐算法</h3>
<p>正如韩寒在《三重门》的后记写的:<strong>我是金子,我要闪光的</strong>。好的内容也是会闪光的,只是需要时间和机会。在各个内容平台中,知乎的推荐算法更加友好,可以将内容推荐给很多感兴趣的人,这对于每个坚持创作的人都是一个很好的机会。根据知乎提供的<strong>热门内容传播分析报告</strong>,一些大V的点赞加速我的答案的传播,在此感谢大家的支持。</p>
<p><img src="/img/remote/1460000019256112?w=662&h=525" alt="" title=""></p>
<p>作为一个内容平台,推荐算法还是非常重要的。不少用户已经养成了通过推荐获取信息的习惯,比如我每天都刷很多次微信的看一看,确实能发现不少感兴趣的内容。但是,一些内容平台的推荐功能很弱甚至于没有,这里我就不点名了。创作者发布博客之后,会发现除了前几天访问量还可以,以后就非常少了,未来的流量只能依赖于搜索引擎。这样的话,对于读者、作者以及平台都是一种损失。今日头条的成功,简单来说,其实就是推荐算法的成功。</p>
<h3>我的博客</h3>
<p>这几年,我一直坚持原创或者翻译博客,大概每周写一篇,现在已经写了接近<strong><a href="https://link.segmentfault.com/?enc=godIDsO9BMZ9WtrkbpVBag%3D%3D.nQfGyQoqiNOJ9IweMAHL5GIwC%2Fd0VKz00VywiuU4dho%3D" rel="nofollow">17万字</a></strong>,阅读量超过1万的其实也不少了,但是写技术博客要想突破<strong>10万+</strong>是一件很难事情,因为中国也就那么几百万开发者。技术相对于各种热点来说,非常的枯燥,其实我也很少看,除非特别感兴趣。有时候确实感兴趣,也不过是收藏到Pocket里面,然后就没有然后了。</p>
<p><strong>既然没什么人看,有时候还得被键盘侠喷,那为什么还要写呢?</strong>这个问题我也问过其他一些写技术博客的作者,因为发现他们的公众号也没什么人看,但是他们依然在坚持写作。</p>
<p>其实,这个问题的答案很简单,<strong>写技术博客是一种非常好的学习方式</strong>。当我们写一篇技术博客的时候,需要对某个技术点非常熟悉,有时候还需要一些自己的思考,而写作的过程中总会发现一些自己不太清楚的地方,需要进一步了解。这样,但你写完一篇博客之后,你对这个知识点已经相当熟悉了,我们的知识体系就通过一篇篇博客完善起来了。</p>
<p>如果大家觉得我的博客还有点意思,不妨看一下我这几篇博客,算是我自己还比较满意的:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=Zngs8qAHNjmFMWcmyTx5KQ%3D%3D.Q8qR2XUQdPoJBSbyrzdA%2BxB2VOcps4sqXo5zQHmjhfGHsvmEZXD7jwyCi5Jn%2FsE1VhkRR6twzD3vsyQmmKOtGw%3D%3D" rel="nofollow">我们应该如何给需求排序?</a></li>
<li><a href="https://link.segmentfault.com/?enc=ukwqHEQY%2F%2Fz84y76QFSr1g%3D%3D.mFJLxk8Tove11cytyf5as%2Ff784P%2Fg65OVQ6PahyaJLTZOqplb0PAd%2BlUExWxGjAnx9GMuENW3F9VaovfBz8u1PgbhLjMg0tz5eS9UtaRAtk%3D" rel="nofollow">不要争了!技术选择没那么重要</a></li>
<li><a href="https://link.segmentfault.com/?enc=KkmI4Ss1KmHAlkX9Y954%2Fw%3D%3D.6PXT8SKFiitYvCb524sBQF37amWoON1ifqEuwSPP96fLUYtVWY5Mlqgzo9l36cY1jP7fwMZMmBKG8ns1fERPYry5W3nree%2BWAYCBo1nCIMY%3D" rel="nofollow">2018年,JavaScript都经历了什么?</a></li>
<li><a href="https://link.segmentfault.com/?enc=ShCgBk8d9iMJpDMkx1sYAA%3D%3D.5V%2F47%2FPQz0%2BrypLaTMmU8IS49jAv4xAHoppiOE9vnkBsg3z6mNzPl%2FLuVMAtcVsCQMqosgbl6Bo8OUpbgk5o0zrHv18CP07cqVBrz8jqyso%3D" rel="nofollow">Fundebug是这样备份数据的</a></li>
<li><a href="https://link.segmentfault.com/?enc=vCc0xmbyz0KvEYrrTPtZGA%3D%3D.rqbnZz6m1r3B3t5EqO4LXAXFlXHL4XHkICoZVlB0qqzff1RBeFtUPlA%2FqLNd3kH6PN1XOT6gXNRZzpXOSKnMow%3D%3D" rel="nofollow">重新思考单元测试</a></li>
</ul>
<h3>反驳某些评论</h3>
<p>每一个创作者应该都知道,认真地写一篇博客或者翻译一篇博客都不是一件简单的事情,一般需要花好几个小时时间。对于我来说,每一篇博客都是牺牲周末的休息时间完成的。但是,对于某些键盘侠来说,一句话就可以把人给怼得非常无语。写几十个字的评论,显然要比写一篇上千字的博客要简单很多。</p>
<p>我写了这么多博客,被怼了无数次也习惯了,很多时候不太想看评论。自己费劲写的博客被莫名其妙地怼了,自然影响心情。当然我还是会去看评论的,因为大部分评论是比较友善,且有所收获的,有时确实能够帮助我修改一些错误。</p>
<p>当朋友告诉我,有人<a href="https://link.segmentfault.com/?enc=G9BShBsyzzGbAC7UUh4L8A%3D%3D.RfizJ4elmhN1LwrmNYewS5TwGgnbu3hisNMiH4v0i1g399KVO8IxDk7AD1w6j2hrspwA82bb4S%2Blo9ZLxUbibQ%3D%3D" rel="nofollow">实名反对我的10万+</a>,这虽然是意料之中的事情,但是也非常扫兴了。</p>
<p><img src="/img/remote/1460000019256113?w=687&h=335" alt="" title=""></p>
<p>这位兄弟比较较真,甚至有点かわいい,不过我也是个较真的人,这里来反驳一下这位兄弟的观点,当然<strong>对事不对人</strong>。</p>
<p>他总结的观点我是完全赞同的:<strong>"代码是用来解决问题的,不是用来秀技巧的,越花巧的代码维护的代价越高。如果有一百种解决问题的方法,请使用最简单的一种。"</strong></p>
<p>但是,<strong>他说的东西和我的回答基本上是牛头不对马嘴</strong>,不知道他在反对我什么东西。我的回答只不过是介绍了10个JavaScript知识点,又没有说非得用这些特性去写代码,谁没事写个立即执行函数啊?</p>
<p>拿闭包来说,大家知道它是怎么回事,看到闭包代码的时候能够理解,需要的时候知道怎么写,面试的时候能够答出来就行了。当然,我们没有必要没事写什么闭包给自己添乱,这是不言自明的道理,不知道有啥好说的。 </p>
<p>再举个例子,JavaScrip异步编程有3种方式:回调函数、Promise以及Async/Await,我一直在<a href="https://link.segmentfault.com/?enc=cmTccMRoX4pY%2FSKmXryLDQ%3D%3D.k4wGwZP95NJpeBz%2F1%2BJP%2FNah1vrDtgjWaGZhtsBHc2NfpEMYbJ7Xk1RK4CKiy5ooCW%2FsMxuFmDYUeytfZnEZ8Q%3D%3D" rel="nofollow">"鼓吹"大家使用Async/Await</a>,因为简单太多了。但是,这就意味着我们不需要理解回调函数以及Promise了吗?Promise是Async/Await的基础,没有它,哪里来的什么Async/Await?至于回调函数,事件监听的时候还是得用吧?</p>
<p>打个比方,我写了一篇介绍汇编语言知识点的博客,如果有人说”什么年代了你还用什么汇编呢?当然得用Java啊“,这是不是有点搞笑?日常工作中,99%的开发者确实不需要用汇编,但是大部分开发者最好学习一下汇编,为什么呢?因为学会了汇编,往下层可以帮助你理解计算机组成原理,往上层可以帮助你理解编译原理。这些知识对于一个优秀的工程师都是必要的知识。</p>
<p>还有一点需要说明,<strong>并不是我介绍的知识点没有用,应该只是现在的你用不到而已</strong>,写上层的业务代码当然无需这些奇怪的特性。但是当你写一些稍微底层的代码,比如开发一个<a href="https://link.segmentfault.com/?enc=Ar0YPYs7FzeZGfH8dWheCg%3D%3D.BnVpBlh98%2BL4vg%2FyniQmzjpYvZIDUmNHsL9nmqRDIUo%3D" rel="nofollow">Fundebug</a>前端BUG监控插件或者录屏插件时,什么立即执行函数,闭包,prototype,apply都是要用到的。</p>
<p>本来想逐条反驳,所谓来而不往非礼也。不过还是算了,他翻来覆去也就一句话,这个特性不能用,那个特性不能用,也没有什么好反驳的。这些特性确实有些陈旧了,大多数时候也没有必要用,但是正如评论区有人说过,这些特性<strong>"best to know"</strong>,至于用不用那是另一回事。我给大家介绍一下这些特性,没有劝大家用这些特性,兄弟犯不着这么激动。</p>
<h3>彩蛋</h3>
<p>我的<a href="https://link.segmentfault.com/?enc=cgYUyJL6Yaacoj52lg4xIg%3D%3D.zFDErUyvyepMBvW9wcFVEOi4iwaA1LeED1trIgWvMN5h220sDt0HPMx85ZDrDJcBJBpc%2BBnG1bL1Ta2x3Bk1JQ%3D%3D" rel="nofollow">回答</a>最重要的是最后1个,前面的知识点可以理解为铺垫。我也是花了点时间想清楚然后再写清楚的,不妨作为面试题,正如我所说的,<strong>能够读懂最后1个,JS水平不会太差。</strong></p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=a4ygy5%2FYm6oUP1NMZAEdHw%3D%3D.8nthacdmgstiBJYrp2rqI2A0Ixyj4b2oXzQ3EcUjKC4%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=NYr3mkVco6yLkCTdC%2FVLsQ%3D%3D.2M3vrwbplUKokk5YBI%2FxWxp8GAWVPxe3G30eTL97lOZHCpbVtxDxwdoQLtp2Xdi8" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=HBHLVEVa0jAYxrQyzEyyEw%3D%3D.1BLBazgQlAaEAXPlvC3hVQJ4g1Ji37TihQRypNeYcio%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=ctSI%2Bpp8OAgdbkm5Hiho3g%3D%3D.pyNi2RQ1ssi4zhsWbstdLBSKBEb7YqslxCaQwUTpR0A7mckD7oDcbNyW6rmzdt7sws0J65ppeJ8dL7Lv%2F%2BwDzZ9t1GcI5aA0HR4EI0hNm1Y%3D" rel="nofollow">https://blog.fundebug.com/2019/05/20/the-first-blog-over-100-thousand-pv/</a></p>
Vue.js@2.6.10更新内置错误处机制,Fundebug同步支持相应错误监控
https://segmentfault.com/a/1190000019157573
2019-05-13T09:55:59+08:00
2019-05-13T09:55:59+08:00
Fundebug
https://segmentfault.com/u/fundebug
2
<p><strong>摘要:</strong> Fundebug 的 JavaScript 错误监控插件同步支持 Vue.js 异步错误监控。</p>
<p>Vue.js 从诞生至今已经 5 年,尤大在今年 2 月份发布了重大更新,即<a href="https://link.segmentfault.com/?enc=AaZv44D5yH2Efa3oOzvZrg%3D%3D.lvRBtfnU1E9JA86J5oap4J%2FBuFKb0yqoSUn50FHfLVVonPCvW30REl%2FOMCaVEWkpfwzXs4oT7bsEWZXY9raV4w%3D%3D" rel="nofollow">Vue 2.6</a>。更新包括新增 scoped slot 语法、性能提升、动态指令参数等等。其中我们最关注的是<strong>错误处理</strong>。</p>
<blockquote>
<h4><a href="https://link.segmentfault.com/?enc=tx%2FDLqcinBUjQSkjwT0cAA%3D%3D.PRwcRF588ImeUjOAtIh5Esqn61p4FX%2Fziscyxs2mtQR9BgiE6F0aU3FN1VnV2VT%2BMJkzDtF80RCqU1o3Q1tlUA%3D%3D" rel="nofollow">异步错误处理</a></h4>
<p>Vue 的内置错误处理机制(组件内 errorCaptured hook 和全局 errorHandler hook)现在也会捕获 v-on 处理程序内部的错误。此外,如果任意一个生命周期 hook 或事件处理程序执行了异步操作,现在可以从函数中返回一个 Promise,Promise 链中任何一个未被捕获的错误都会被发送给错误处理程序。如果使用了 async/await,则会变得更加容易,因为异步函数隐式返回 Promise:</p>
</blockquote>
<pre><code class="js">export default {
async mounted() {
// if an async error is thrown here, it now will get
// caught by errorCaptured and Vue.config.errorHandler
this.posts = await api.getPosts();
}
};</code></pre>
<p>根据官方介绍,错误处理的改进包括两个方面:</p>
<ul>
<li>捕获 v-on 处理程序内部的错误</li>
<li>异步 Promise 错误</li>
</ul>
<p><a href="https://link.segmentfault.com/?enc=94QhDnfGyMk3ywAzSOSFJw%3D%3D.qLlsdkKdb4BHnXB2DZAtNmAdX6yfZtd4iRKXma0jbc0%3D" rel="nofollow">Fundebug</a>作为最专业的 BUG(错误)监控服务平台,已经服务数千家企业,数万名开发者。据统计,所有的前端项目中,有<strong>22.5%</strong>使用 Vue.js 开发。之前有使用 Vue.js 框架开发的客户反馈有 bug 监控不到。此次 Vue.js 更新,我们对<a href="https://link.segmentfault.com/?enc=awRezrfhTrw1nqT0pkQAYQ%3D%3D.VjXLk5Dqzm7uJjghRVZWy1yxxRdz4SifLcl6bDVjN4%2FiK6aQCwL%2BlDYEmSrdD%2FT0yZNpBDx1otaOVAAVFRr%2FkWLeh7hA83XqRUgtg%2BevhLI%3D" rel="nofollow">JavaScript 的监控插件</a>做了相应的更新,来更好地支持使用 Vue.js 框架开发的应用错误的监控。</p>
<h3>错误监控测试(TodoMVC)</h3>
<h5>1. 通过 v-on 定义事件</h5>
<p>我们使用经典的 todoMVC 项目来进行测试。</p>
<p>首先接入 Fundebug 监控插件,在 Fundebug 官网创建一个 Vue.js 监控项目。</p>
<p><img src="/img/remote/1460000019157576" alt="" title=""></p>
<p>接下来根据接入代码,安装 Fundebug JavaScript 和 Vue 插件:</p>
<ul><li>通过<code>npm</code>安装<a href="https://link.segmentfault.com/?enc=OWcLdsoF1G1K1fUEZ6zWtg%3D%3D.iGUsXrFoUM3MwJsiPylGB4BxHbxAFxiO4ZP6aXtBQtMv9VS6n885Vfldk1ZdbUoHWtJjYgEI9j%2FSY%2F1iaaI1lQ%3D%3D" rel="nofollow">fundebug-javascript</a>与<a href="https://link.segmentfault.com/?enc=5%2Foib3jxevw4uWFUx3uoiQ%3D%3D.aDJ3aVxul4g0vz6N3NucdoWEGDvgyNUsQV2s0ZXm5kLJwwTn0OG0OzG%2BmO4YMZSq" rel="nofollow">fundebug-vue</a>
</li></ul>
<pre><code class="bash">npm install fundebug-javascript fundebug-vue --save</code></pre>
<ul><li>配置<code>apikey</code>
</li></ul>
<pre><code class="javascript">import * as fundebug from "fundebug-javascript";
import fundebugVue from "fundebug-vue";
fundebug.apikey = "API-KEY";
fundebugVue(fundebug, Vue);</code></pre>
<p>其中,获取<strong>apikey</strong>需要<a href="https://link.segmentfault.com/?enc=2ddLLzn5LEVHx3prx3vLtQ%3D%3D.pEYvv68aLH1ToPe%2F3Tdf%2BZVCXcLBVdKHFqKowvfiMzHgiHHocfE4IJHhhrxsWQjn" rel="nofollow">免费注册</a>帐号并且<a href="https://link.segmentfault.com/?enc=iuFNm%2BzYQ9bxw9vQAicUtw%3D%3D.fHIb4Z%2FJTSnHmYdM0oXxsT2FfxYmhAn%2F6r%2BAQl7YqWkE2Z1VKTc%2F7kkpqjaVio%2BG" rel="nofollow">创建项目</a>。</p>
<p>然后,我们对右下角的<code>Clear Completed</code>按钮对应的代码进行更改,通过<code>v-on</code>来定义点击事件,然后对应的<code>deleteCompleted</code>函数故意将<code>todos</code>写成<code>todo</code>。</p>
<pre><code class="html"><button class="clear-completed" v-show="completed" v-on:click="deleteCompleted">
Clear Completed
</button></code></pre>
<pre><code class="js"> deleteCompleted() {
this.todos = this.todo.filter(todo => !todo.completed);
}</code></pre>
<p>点击<code>Clear Completed</code>触发报错:</p>
<p><img src="/img/remote/1460000019157577" alt="" title=""></p>
<p>Fundebug 成功捕获该错误:</p>
<p><img src="/img/remote/1460000019157578" alt="" title=""></p>
<h4>2. 异步 Promise 错误</h4>
<p>通过<code>axios</code>发送一个 GET 请求获取数据,然后将返回数据处理。假定不小心将<code>data</code>写成了<code>date</code>,那么<code>data.length</code>会触发错误。</p>
<pre><code class="js">deleteCompleted() {
return axios
.get("https://jsonplaceholder.typicode.com/todos/")
.then(response => {
let data = response.date;
let len = data.length;
});
}</code></pre>
<p>程序运行后,Fundebug 成功捕获该错误:</p>
<p><img src="/img/remote/1460000019157579" alt="" title=""></p>
<h4>总结</h4>
<p>Vue.js 更新到 2.6.10,对错误处理提供了更加强大的支持。Fundebug 的 JavaScript 监控插件支持 Vue.js 项目中<code>v-on</code>和异步错误的监控。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=8hRFi3O15DKinCy7Z8DnTg%3D%3D.%2FAVfBjcRdWGsJeVPcQfuRDV2B8DiibRZeMfdKYRYGFs%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=95G7mKSb3bl%2B7teANsLicQ%3D%3D.O27H%2BNyUv6DXANN9BgmFYLwGB7uADkvz9HVHBQzn5t9a2phxJaG0cls3C6YXLYqG" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=pl%2F4r4d2a3O2qFAdqir%2BfQ%3D%3D.5%2FIk4nVUmNfKQ5D6gimIXv6mOoYBfzM%2BuMqWmmJQ7ms%3D" rel="nofollow">Fundebug</a>以及本文地址:<a href="https://link.segmentfault.com/?enc=qTqc9CiAoEuz8ZsKspZ6%2Fg%3D%3D.qwlKVxGbtakcUvfloue7Za1tgDfc3EMDAY7nee4UfCS0tDmDWvbGMphkpqlXynEECHSVnJJCpgGitK5iqazr0qxmIgwBDasyyjLtcL6Vwxo%3D" rel="nofollow">https://blog.fundebug.com/2019/05/13/fundebug-support-vue-2-6-10/</a></p>
Fundebug 微信小程 BUG 监控插件更新至 1.2.1,优化错误上报次数的限制算法
https://segmentfault.com/a/1190000019041367
2019-04-30T15:53:37+08:00
2019-04-30T15:53:37+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> <strong>1.2.1</strong>优化错误上报次数的限制算法,新增<a href="https://link.segmentfault.com/?enc=i3QzFBZaffLC8ME2iL9%2FHw%3D%3D.fvTM%2B%2FHKQyYaScVEp5y9An0Yvocc5iqtGtpf7TCpv%2BAeGq3E6SiC6LJg4faHJFSld32617s0mlD0tL5YovZjzyYEz97xMUs0u2hC8nZbE3Q%3D" rel="nofollow">silentHttpHeader</a>配置选项,请大家及时更新哈!</p>
<p><img src="/img/remote/1460000018947435?w=900&h=383" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=b7SLdNrg8CdRSl7fp%2FrfnQ%3D%3D.Q5IiJJFt1JHS0Uoe6ULYGl5bU6Ymnotlb%2FC5Trld%2FfU%3D" rel="nofollow">Fundebug</a>提供专业的微信小程序 BUG 监控服务,可以第一时间为您捕获生存环境中小程序的异常、错误或者 BUG,及时给开发者发送报警,帮助您快速修复 BUG。欢迎大家免费试用,也欢迎各位用户反馈建议或者问题。</p>
<h3>优化错误上报次数的限制算法</h3>
<p>在小程序生命周期之内,Fundebug 最多错误上报次数为 50 次,这是为了避免无限循环导致无限报错。这里所说的生命周期,指的是小程序仍然存在于内存里面。</p>
<p>根据微信小程序的<a href="https://link.segmentfault.com/?enc=FTRXkmBZzcDcyJ%2BVEpc87A%3D%3D.vj1tD%2BMNs%2BysBUzqV5W4NtY0HIZkvmOP53th%2F5sPQKdJsrIrLrp1BpRUeXGFsRbu8MmE6PWD8hezH0k54zcxqAYqC%2Bx%2FXAOaU0TuMm2bjBs%3D" rel="nofollow">文档</a>,<a href="https://link.segmentfault.com/?enc=fVGvGaGqz3zrTVublyUpfA%3D%3D.9XYag9qr%2Fdgdnn5xxttFizM4RFF1WezsjzP0waH8Kh3JkQtHhUWqkEUESatYNeONGLdYcLFhqIu1ZQxUk%2FxRP9KqhT3dYAt8D2ogcRUv6KA%3D" rel="nofollow">wx.request</a>的最大并发限制是 10 个。因此,Fundebug 同一时间上报的错误数最多为 5 个,这是为了避免占用微信小程序的网络请求的并发数。</p>
<h3><a href="https://link.segmentfault.com/?enc=IzktnhU4cfYYuRkd%2BYZbww%3D%3D.cVm42To48hORxVGeF8izZXEx1e64YIGvaMNYldgIhBVybCVxfELZPN57xxmTGuIa6m%2FjnxmJVC9a9zF8hBqdisAiU02fYUhXeLA18pi7U8M%3D" rel="nofollow">silentHttpHeader</a></h3>
<p>如果你不希望监控 HTTP 请求错误的 Header 的话,可以将 silentHttpHeader 属性设为 true:</p>
<pre><code class="js">fundebug.init({
silentHttpHeader: true
});</code></pre>
<p>最后,感谢 Fundebug 用户<strong>熊文</strong>的反馈。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=ozPpmHQ%2Fk6Qv8aLnS3uGcA%3D%3D.A1pVzMFGEa325FIpDKBkY6pG%2BtoN1U1cnfbtIvwIONR11m3lzZiAm9cAcHfyFx%2BZyAQrt%2BbOWn2w9rM1%2BWe1LnSW%2BimNtFHmg9NBJjWgwPM%3D" rel="nofollow">Fundebug 文档 - silentHttpHeader</a></li>
<li><a href="https://link.segmentfault.com/?enc=CEYOovvTIZmYveJqiNyAeg%3D%3D.2w8iI%2FMnLszTbTYmbfs8cLEy%2FmE%2FRBs8vq5ODxAhu9kCxZ1tTtYhklhEbpRXkC%2BogCR1kZLhjrFLICMj4ERjCWDqBlu31j3m6mHBZssZaQk%3D" rel="nofollow">微信小程序文档 - 网络</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=erGr%2BaNvAh8FI3j9GjDu5A%3D%3D.%2Ff%2BGb0zsmjZAKNGIuxw6GukJiyTPQ5uljvlMWh7NSpk%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=qHWxXjxuRtdMfgXQN3BKsQ%3D%3D.oj4UEP3098k4rxfMik0ySrg2IEeD8aJWvffbl30H6aDOYx5eGGELBz8idOfbSvYw" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=sJWe4ZWZOXSt2DFy3tzlWg%3D%3D.pqr%2B7PGJn5qQnt7Xmn8rr1skX9h8gDNBOIu3a%2BNUt%2BA%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=2GV9uZsQ1avPVA6oQrjblw%3D%3D.UoM%2Bak9%2BM5w%2FGrMhaaPtWbYJ8hs1vaELqlPp7o%2F4c6wurMGlxsRpzdCuo8G3Eu8rYF8Wl%2Bp0DAFLrSvd12x1rIRfQjk3ZAu8SYOhNJmguwc%3D" rel="nofollow">https://blog.fundebug.com/2019/04/29/fundebug-wechat-miniprogram-upgrade-1-2-1/</a></p>
Fundebug支付宝小程序BUG监控插件更新至0.2.0,新增test()方法,报错增加Page数据
https://segmentfault.com/a/1190000018994424
2019-04-26T10:46:02+08:00
2019-04-26T10:46:02+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> <strong>0.2.0</strong>新增<a href="https://link.segmentfault.com/?enc=8cpf6ABdx%2FwTev66Wv7E6A%3D%3D.QZgPs44w2tBjI%2BQYVQxJ9%2FkEk0Fr%2BxYZjEoIjO%2Fqm8YABhJG0y4doTIW8oh7CtfN4a7cDqLXyzhTBgfMEb193A%3D%3D" rel="nofollow">fundebug.test()</a>方法,同时报错增加了Page数据。</p>
<p><img src="/img/remote/1460000018994427" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=N%2FnPfllj1t1fbXJLnEwdVQ%3D%3D.YTcvndpmV1T9hv2FmecJfwAyEVRLdhSZgoIGn3S6t2c%3D" rel="nofollow">Fundebug</a>提供专业支付宝小程序BUG监控服务,可以第一时间为您捕获生存环境中小程序的异常、错误或者BUG,及时给开发者发送报警,帮助您快速修复BUG。欢迎大家免费试用,也欢迎各位用户反馈建议或者问题。</p>
<h3>test(name, message)</h3>
<p><a href="https://link.segmentfault.com/?enc=kJHYw4mIuVidl505c1J5dQ%3D%3D.gYOMXIGyfKDLh75X9XsuXX5mRVoKEelM7gP7Ebew807z9n6fFWrqM%2FqoUZVa25tWgGDye%2BiI8rBS2vzKzydFaw%3D%3D" rel="nofollow">fundebug.test()</a>用于测试,可以将测试数据发送到Fundebug,并收到报警邮件。</p>
<ul>
<li>
<strong>name</strong>: 错误名称,参数类型为字符串,默认值为"Test"</li>
<li>
<strong>message</strong>: 错误信息,参数类型为字符串,默认值为"Hello, Fundebug!"</li>
</ul>
<p>示例:</p>
<pre><code class="js">fundebug.test()</code></pre>
<pre><code class="js">fundebug.test("Test", "Hello, Fundebug!")</code></pre>
<p>fundebug.test() 主要用于测试,它发送的错误每次都会报警邮件(每天的限额是 20 封),这样可能会给您造成困扰。为了避免重复报警,请使用其他 API 记录错误,这样同一个错误将只会在错误数达到阈值(10, 100, 100...)的时候报警。</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=0e9v2tOnPkQnF8VXIUzSvQ%3D%3D.wCUo2pBO1RRrNurn9YgIj719VfzmfgUBOI7izUxdUHUMLx5WisZ6%2B0zrJUi1HZcBeZe9YDWyUxgP5nBSJIZBgg%3D%3D" rel="nofollow">notify</a></li>
<li><a href="https://link.segmentfault.com/?enc=PK9RT5szelmayin%2Fk8CrYg%3D%3D.0rzyDrzM8SilqyMenCv7MzQr99zxr2tnC61w1X0OW959lHTj6Ki2c6WmWfN8qhdjOAAYvKiOLLZ1f35KrGBNkQ%3D%3D" rel="nofollow">notifyError</a></li>
</ul>
<h3>Page</h3>
<p>Fundebug插件会调用getCurrentPages方法获取报错页面的Page数据,与错误数据一起上报:</p>
<pre><code class="javascript">{
"route": "pages/index/index",
"_viewId": "1556021552987",
"data": {
"title": "Alipay"
}
}</code></pre>
<p>如果不需要收集Page数据的话,可以将<a href="https://link.segmentfault.com/?enc=mZspyiFCIF15tuc28v%2Fucg%3D%3D.%2BdCRrj9gQGhKteRYl9%2F%2BzdARWNOCY7P8%2B8E08Slt4mqkFjh6%2FqUYn7pGN1aLhSypVIxCF8gL1xMkECfTmLMaj081Dh%2BzrlXM913JfDSxt4I%3D" rel="nofollow">silentPage</a>属性设为true:</p>
<pre><code class="javascript">fundebug.init(
{
silentPage : true
})</code></pre>
<p>最后,感谢 Fundebug 用户<strong>闵胖胖</strong>的反馈。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=sFUnk56yXm7sGFiPmQFYYQ%3D%3D.V8hSzH8VRTfaUBVXrlM%2BXbpJw46RicAbBKRWjsKSD8LmUFa8VT9DhIAOjqbVDd1US94uDoHnVjReNMLpGXjTAg%3D%3D" rel="nofollow">Fundebug文档 - fundebug.test()</a></li>
<li><a href="https://link.segmentfault.com/?enc=SLUt7qSPmWTrKra1Slq%2BJw%3D%3D.e9XYH2kZnjlrqXFwgq%2BAVDlamy7V2AvBq2LctZcO46ZK%2FaYY1m7HuWRf62jFLvfPlsnc%2Bz9TKJ%2FrIRgpxEO9MGnVoZwAwGWcSZCQA%2FM2IkA%3D" rel="nofollow">Fundebug文档 - silentPage</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=PRuHtuvS20%2BUV%2FcEHliUhQ%3D%3D.c%2BdZolN4Sx47u%2BLh79nItsl7i9%2BORjDG31m1hjoHib4%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=ZRLqpUrab2Gk%2F8gkGRp3UQ%3D%3D.ly%2Bkt3Now7hOf9wpyip%2BbniiZNcIdtILtbBGAStwVZh%2FLf1pThQGeMEl4uAqz3Fz" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=tZX%2FEOw8URnOmvzi1dZ0ug%3D%3D.Q5tuNUWoSSE4OvmFUBmHmhCfh1we827aTfD%2FQ2kGtsY%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=TsVmOf6CNvRISRO8mFkThQ%3D%3D.w55J9pbDL7vZs%2B6kEBvOVhx%2BNm%2FfsGEpNNrOU53zpfZ4hVK7YnL5m0nHj7G7yW623EkkVraQePyhsK0UfXqPqjJUZCPsDAeDd51OLEPLJpU%3D" rel="nofollow">https://blog.fundebug.com/2019/04/25/fundebug-alipay-miniprogram-upgrade-0-2-0/</a></p>
Fundebug微信小程序错误监控插件更新至1.1.0,新增test()与notifyHttpError()方法
https://segmentfault.com/a/1190000018947432
2019-04-22T14:54:32+08:00
2019-04-22T14:54:32+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> <strong>1.1.0</strong>新增<a href="https://link.segmentfault.com/?enc=cB8oQ3fCiNIDhvnd3ke3sA%3D%3D.NxpaVsCar3odrybULLKNmTELkg9kDndXmdmnwvn3NJfaQzyVKczo5SBEedd9Tbf1yyzI8FFdaiJMyVlwq0Zdzg%3D%3D" rel="nofollow">fundebug.test()</a>和<a href="https://link.segmentfault.com/?enc=TvbNH46v0mlTcdvvK%2BnHHg%3D%3D.pAxU7tc9xh5m67SMhLW5o9eM7LMAwuTCmJ3t7f0BkRb8js9Z28eYmfYijo0c4t4%2BK3HtHo7SLleKHc0ibKZ%2F%2BRBxOrBDYTRtv8700OrF9Vo%3D" rel="nofollow">fundebug.notifyHttpError()</a>方法,同时大小压缩至<strong>15K</strong>。</p>
<p><img src="/img/remote/1460000018947435?w=900&h=383" alt="" title=""></p>
<p><a href="https://link.segmentfault.com/?enc=KN39dCN%2FtDKbRtubm2zpbQ%3D%3D.7pWrD0EhdMbmncASBoVZ7aPwrlTSbf11cE1uxRiWXzA%3D" rel="nofollow">Fundebug</a>是专业的小程序BUG监控服务,可以第一时间为您捕获生存环境中小程序的异常、错误或者BUG,及时给开发者发送报警,帮助您快速修复BUG。欢迎大家免费试用,也欢迎各位用户反馈建议或者问题。</p>
<h3>test(name, message)</h3>
<p>使用 fundebug.test()方法可以用于测试 Fundebug 插件。</p>
<p><strong>name</strong>: 错误名称,参数类型为字符串,默认值为"Test"</p>
<p><strong>message</strong>: 错误信息,参数类型为字符串,默认值为"Hello, Fundebug!"</p>
<p>示例 1 : 没有参数</p>
<pre><code class="js">fundebug.test();</code></pre>
<p>示例 2 : 带参数</p>
<pre><code class="js">fundebug.test("Hello", "This is a Test");</code></pre>
<p>fundebug.test() 主要用于测试,它发送的错误每次都会报警邮件(每天的限额是 20 封),这样可能会给您造成困扰。为了避免重复报警,请使用其他 API 记录错误,这样同一个错误将只会在错误数达到阈值(10, 100, 100...)的时候报警。</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=XyfazHlsKJHDUx8Ezzc%2Fgw%3D%3D.4Ucfa2vEPlQIc%2B2iEtVNK2W%2FYKP146wmUgrqwE03zkgrzXQX8cEnKlYWshVcMUk8TbrUexEE%2BpSxV8tHs1FlvA%3D%3D" rel="nofollow">notify</a></li>
<li><a href="https://link.segmentfault.com/?enc=pV8qBA9eZt%2BTxsj0thpCNg%3D%3D.UEANQVjb9wod4eM%2Btd82QpN6y8%2BghNS9eNnfmVTesLMMYemXnpgdWUaVpsFDuaJ%2FVVeCckOsd9%2Feo9hCIrNxLA%3D%3D" rel="nofollow">notifyError</a></li>
<li><a href="https://link.segmentfault.com/?enc=%2Ffnh25A4i1PLhc7oFtYHqg%3D%3D.tgGuZAtvmY%2BS1JMUotWZeELRbk5EbuxJCMvx212ihIICYu04nY5uYy5U56nK7q3N%2BNRof8s2WkQYkjnS%2B1LHouji%2Fz4SzOJpJoeveu%2FNtxg%3D" rel="nofollow">notifyHttpError</a></li>
</ul>
<h3>notifyHttpError(req, res, option)</h3>
<p>使用 notifyHttpError,可以将 HTTP 请求错误发送到 Fundebug。</p>
<p><strong>req</strong>: HTTP 请求参数,参数类型为 Object,其子属性与<a href="https://link.segmentfault.com/?enc=XX6d6Fy04Oc1Xr29EGE%2FjQ%3D%3D.yvEdrEP1TSLMO%2FzfQX%2Ff1Lbrx97F8%2F%2B7weFtgMbIJaVUlYl73DjdniigosQMM4xJACz0IqW5jFtaxoUg64JFAiKgroR4Ddwnnt%2BPUgKIvkc%3D" rel="nofollow">wx.request</a>的请求参数一致,如下:</p>
<ul>
<li>method</li>
<li>url</li>
<li>data</li>
<li>header</li>
<li>dataType</li>
<li>responseType</li>
</ul>
<p><strong>res</strong>: HTTP 返回参数,参数类型为 Object,其子属性与<a href="https://link.segmentfault.com/?enc=wcT6gjyaZfrPzjI%2BRWMkEA%3D%3D.LtAWoW%2F9T5o70RnQiDlOXPSj%2BO2u0nsvbLNnuj5acmPJIbTXnapziTapkkZ38h%2BWW0czRehjKRIbO9JAci21tRDusbru%2FtAC7sVW9iTYjv4%3D" rel="nofollow">wx.request</a>的返回参数一致,如下:</p>
<ul>
<li>statusCode</li>
<li>errMsg</li>
<li>data</li>
<li>header</li>
</ul>
<p><strong>option</strong>: 可选对象,参数类型为 Object,用于发送一些额外信息,比如:</p>
<ul><li>metaData: 其他自定义信息</li></ul>
<p>示例:</p>
<pre><code class="js">wx.request({
method: "POST",
url: "https://example.com/create",
data: {
test: "test"
},
success(res) {
fundebug.notifyHttpError(
{
method: "POST",
url: "https://example.com/create"
},
res
);
},
fail(res) {
fundebug.notifyHttpError(
{
method: "POST",
url: "https://example.com/create"
},
res
);
}
});</code></pre>
<p>最后,感谢 Fundebug 用户<strong>无事忙</strong>的反馈。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=acJ%2FrHrAd3XBW3QFpw5mIQ%3D%3D.PcM8CGqgm7D8f%2B4%2B2aBEcb8iMkC4EcL%2FHGBC%2BvVTA2SAnkVIJ%2ByUhboIa5ihSpSNhg7EmpbArlhFkrOaU2B%2FFQ%3D%3D" rel="nofollow">Fundebug文档 - fundebug.test()</a></li>
<li><a href="https://link.segmentfault.com/?enc=b671CAEApdEo3jAMi1T3Sw%3D%3D.RDKwpLOfz6XSyvnuB5DI14f5h96OlOK49pqCGOADruwOeWOEuTPNxqnZ4yK5i8zMH3BlXkTRZu5Jz5XmXX75Uf3ojD%2BfbtDCCKGRGTpwqRw%3D" rel="nofollow">Fundebug文档 - fundebug.notifyHttpError()</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=HgoTqCfNjq3o4zFF7NTAqA%3D%3D.PvGY5vOAAR4kWxjjqu9rN748IOPesW8i9IjNwIj5jgg%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=2PjPVumJxUinhKD3dEgaNg%3D%3D.R8KtoSerHeZxu49JKfsQzDuulmncQYNHoubcaYm4%2FjZo4Xe2ROk%2FccdT6lHgXISy" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=M38FvHwt1PyuhttJyC4QUQ%3D%3D.0lia7DGO2EsSncqQYmabjrJYkVRbD5ZrCq2RkqoOMm4%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=%2BuXayjt0ooEhYVrkRcQ1vA%3D%3D.J9oQpgwp43d%2BFBBtYw59Alv5a1ofQwzWVF0XYHvxAkOSrIk7FR8jmZyHyTrbkSkkBoxCOkm%2Fs6kOsvdkzf67GsMT9Kp5vAhYIBqj2NVTtI4%3D" rel="nofollow">https://blog.fundebug.com/2019/04/19/fundebug-wechat-miniprogram-1-1-0/</a></p>
为什么很多人开始反对996了?
https://segmentfault.com/a/1190000018880231
2019-04-16T10:08:18+08:00
2019-04-16T10:08:18+08:00
Fundebug
https://segmentfault.com/u/fundebug
6
<p><strong>摘要:</strong> 反对996是有更深层次的原因的。</p>
<p><img src="/img/remote/1460000018880235" alt="" title=""></p>
<p>也许不少人和我的感觉一样,996这个话题持续的时间有点长了,这挺神奇的。因为,通常一个热点最多持续三四天左右。</p>
<p>而996这个话题,竟然从年初聊到现在,这里不妨梳理一下最重要的3个时间节点:</p>
<ul>
<li>1月19号,<a href="https://link.segmentfault.com/?enc=A33Ts3HVkEUe0qMlggHXjA%3D%3D.Lqn0AFvKyeJph1GxjpXwvc01hTnB3MbJ2FJLxnXVXqO7CNv%2Fba14SqF%2BeoOyT2GE%2Ba9NLFTNmUVL5oGOuXXHvf6PD8V9Yd9BVPX%2Bhc3Ixc806zhquW1RvUXtqcGGL0PsP1ritlehpBkElSTZoAZL1MuI8dgsjBNdN2W%2BR7EaTJ4zOzuPVDPQvNQAuRqD3wbyIbIJlE9lf2yMhkmXSaK9B%2BT1Pdr0Zf%2FKGHexmfyLASY%3D" rel="nofollow">有赞员工在脉脉爆料公司强制实行996</a>;</li>
<li>3月26号,某程序员在GitHub上发起<a href="https://link.segmentfault.com/?enc=9Ys%2BQSAlbTLcveCAIjWv6Q%3D%3D.2PHeXarlbmYwewnQzwipCzGfBjqCVKIc23GBxL%2BfsPBmE0YbqHSAAagZHsLWx941" rel="nofollow">996.ICU</a>开源项目,不到一个月时间,获得22万个Star,成为GitHub网站Star数最多的项目;</li>
<li>4月12号,<a href="https://link.segmentfault.com/?enc=uc08RXyFixm9nF9D6tZ%2Frw%3D%3D.sFZGjeXgqDiRhUEAl6CShLr91%2FbCMvbey5cktDuuIDqb2Rl6n7fCuX51m%2FQ1Eu4PwdHroEA0fvauSfKJm9ZZdQ%3D%3D" rel="nofollow">马云谈996</a>发布,称“能做996是一种巨大的福气”;</li>
</ul>
<p>从百度指数也可以看出来,马云彻底引爆了996这个话题。</p>
<p><img src="/img/remote/1460000018880236" alt="" title=""></p>
<p>对于996,支持者觉得天经地义,反对者觉得不可思议,究竟谁对谁错,暂时不去说它。我们来先聊聊<strong>为什么996突然这么火了?</strong>或者说,<strong>为什么很多人开始反对996了?</strong></p>
<p>简单地说吧,时代变了,观念也变了。</p>
<h3>中国人均GDP已经接近1万美元</h3>
<p>2018年,中国的GDP是13.6万亿美元,这就意味着中国的人均GDP已经接近1万美元。与发达国家相比,我们还有很大的差距,但是生活也算是"丰衣足食"了。</p>
<p>中国人有一句很实在的问候语,“你吃了吗?”,我总觉得这个问题有点古怪,因为对现代人来说,吃没吃不是问题,吃什么才是个让人头疼的大问题。其实,稍微了解历史的人应该知道,中国人是在最近几十年才正真解决了温饱问题,我们的祖父辈,甚至父辈都经历过没东西吃的疾苦。现在时代变了,已经越来越少的人会去问“你吃了吗?”。当收入达到某个阈值的时候,我们的生活方式自然会有所改变,简单的一个问候语也能说明问题。</p>
<p>那么,当人均GDP接近1万美元的时候,对我们来说意味着什么改变呢?也许是时候改变996了,我们可以听听环球时报的胡大主编是怎么说的:</p>
<blockquote>我个人认为,舆论场这一轮对996的批评有其积极意义,这也是中国人均GDP达到一万美元左右人们对美好生活的新理解和追求。中国的高质量发展其实包括工作效率的提升,以更加文明、人性的劳动时间安排。我相信很多大公司将会面临优秀员工对长期加班意愿减退的现实压力,全凭“弟兄们”一起玩命工作、支撑公司锐气的时代文化实际上已在动摇。</blockquote>
<p>反向思考一下,如果科技不断进步,经济不断发展的情况下,现代人过得越来越累,那我们努力的意义是什么?如果人工智能时代,人类还需要拼命工作,我们要这AI有何用?</p>
<h3>95后已经步入职场</h3>
<p>22岁大学毕业参加工作的话,那么95后差不多工作2年了,不同年代的人有代沟,这是我们这些“长辈”不得不承认的事情。</p>
<p>举个例子,大部分长辈觉得我们必须买房、必须结婚、必须生小孩、必须生二胎,这让我们感觉有点莫名其妙,有时候也有点崩溃,生活哪有这么多必须啊,太累,还不如按照自己想法去生活,不影响其他人就行。</p>
<p>崇尚自由、享受生活、充满个性曾经是贴给我们8090后的标签,这些也适用于新一代的年轻人,只是他们会比我们走得更远一些。我不是95后,说实话也不太了解他们的真实想法,但是我想有2点是确定的:</p>
<ul>
<li>他们的想法和我们不一样;</li>
<li>他们会更加崇尚自由、更加享受生活、更加充满个性;</li>
</ul>
<p>长辈们再去拿成功学去教育下一代也是徒劳的,因为每一个世代的人对于成功的定义是不一样的。你们的成功是没完没了的赚取名利,他们的成功只不过是简单而快乐的生活。你们热爱工作,他们更热爱生活,不理解拉倒,但是也没有必要去洗脑对方,改变不了的。</p>
<p>996是两代人的价值观冲突,这至少不是什么意识形态对决,还是可以和解的,而方法无非就是提高工作效率,减少工作时间...</p>
<h3>结论</h3>
<p>996只是经济飞速发展时期的一种比较<strong>变态</strong>的工作方式,随着时代的进步,观念的革新,它一定会被改变,相信这次996辩论只是一个起点。正如国父所言,”天下大势,浩浩汤汤,顺之者昌,逆之者亡。“,谁也改变不了这个趋势,谁也阻止不了人民群众对美好生活的向往。</p>
<p>对于996的支持者们,我只能说,<strong>我就是喜欢你看不惯我又拿我没办法的样子</strong>。哈哈。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=psEz3MGIhu65vtrsXSrHvw%3D%3D.wQ48Ugx%2Fs2R%2FIoDesqbz0959pdwyMuOfpYHRI2cAVFc%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=TJlglKbPHBtDpOSj5Mh2Wg%3D%3D.adjlQrlJvt0bFVuM6pduNsDqprvVbt2ra6DbPePIS63c4eFJJoutdN2JiFdd3Lrz" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=yNmiyZoOQxqhcYNdQCvG4A%3D%3D.yGFSQvDDXvt%2Fmjz94h3BdIB6l2unACvVe2i%2F8NqOjIg%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=RqVDkVoZfPxByo6vSc6PXw%3D%3D.cRAj%2BPEw12SorFZJnmA49FEaJ2J4iuAMYvIlnQH6xuVMJ0t52Psn0TeIKPGZbUBRWVyZGvkvWUZi1qC%2Fl2UlaA%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/04/16/why-do-people-against-996/</a></p>
Fundebug支持浏览器报警
https://segmentfault.com/a/1190000018820609
2019-04-10T15:59:35+08:00
2019-04-10T15:59:35+08:00
Fundebug
https://segmentfault.com/u/fundebug
8
<p><strong>摘要:</strong> 除了邮件报警和第三方报警,我们新增了浏览器报警功能。</p>
<h3>邮件报警与第三方报警</h3>
<p><a href="https://link.segmentfault.com/?enc=hcB78vrw9bGtVv9NKpqMww%3D%3D.LQuUrGdMOXel9gg7eN3awU8qzzC3y6wJy1CJRsE6yec%3D" rel="nofollow">Fundebug</a>是专业的应用BUG监控服务,当您的线上应用,比如网页、小程序、Java等发生BUG时,我们会第一时间发送<strong>邮件报警</strong>,这样可以帮助您及时发现BUG,快速修复BUG。</p>
<p>另外,我们还支持各种<strong>第三方报警</strong>方式,如下:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=QlFqpSE7QrD0l08AyecEAw%3D%3D.VybcVtKNq9DNW2R1Fvoty0tVzCIv2bLSsxJeLUzzQznrGFwCeJNC1gclK7xiIfDm" rel="nofollow">钉钉</a></li>
<li><a href="https://link.segmentfault.com/?enc=5lTO6HhiUnv1v0dlNBimyw%3D%3D.cBMu729QtptnvntJiVBC7Em2Zrbj89%2Bkp6iVp5DZssWWNecXmnH7HIBbn16Vrqia" rel="nofollow">Slack</a></li>
<li><a href="https://link.segmentfault.com/?enc=kXr06gqy1sN3Ow2Gl4C%2Feg%3D%3D.oU1zB6hDPiobR2TtL4%2BxcpKhVM1FZCSeePuFxXW%2BQz8Qcy0tkscH2Se3yFmb2Lsx" rel="nofollow">倍洽</a></li>
<li><a href="https://link.segmentfault.com/?enc=6FXw5eRSxRI9928uLVqvIg%3D%3D.lYqfeb9kItP%2BKRlu9AREm%2B4ixB5fnI2i8kn3ymfAXYBLdjEE9KVqYdbHnZ4Td6Kv" rel="nofollow">简聊</a></li>
<li><a href="https://link.segmentfault.com/?enc=JQaJORiowuhGaYgvy3q1jg%3D%3D.FjJRoBDLQx2mW%2BmHn28yC2Hb4LI%2FFDzXbaGQXkApint2cMocdIXSk6L%2BtMHQMmdG" rel="nofollow">Worktile</a></li>
<li><a href="https://link.segmentfault.com/?enc=bCzULC3G79ZeXse4NLyEPA%3D%3D.8Tviu1XEkIg3NiRXKGKAlo2j6rQbV2QBDBsb7sEVFUDVRiD5yHfWB8ZRxcCvtpMs" rel="nofollow">零信</a></li>
<li><a href="https://link.segmentfault.com/?enc=YxcqLlV9bEI4MUwQRY3jbw%3D%3D.tpiAvDXYSTYM6OrS%2B8awjMHp96lv6EJ5rLHqBA%2FWIPAeVEZbk9gMJTsyFhywMRg5" rel="nofollow">自定义Webhook</a></li>
</ul>
<h3>浏览器报警</h3>
<p>为了帮助用户第一时间发现BUG,我们支持了浏览器报警。</p>
<p>默认情况下,如果您保持Fundebug控制台打开,我们会每隔1个小时检查是否有新的错误出现,并且通过浏览器提醒告诉您:</p>
<p><img src="/img/remote/1460000018820612?w=400&h=80" alt="" title=""></p>
<p>您也可以在项目设置页面对该功能进行配置,选择开启或者关闭浏览器提醒,或者配置浏览器提醒的时间间隔(取值为60到3600秒之间)。</p>
<p><img src="/img/remote/1460000018820613?w=400&h=123" alt="" title=""></p>
<p>最后,感谢Fundebug用户<strong>大宝</strong>的反馈。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=xJ1CjdRLD%2BzQZ%2B0I9CjZMw%3D%3D.v69JFw68U1yDEqTaz1fM8Hx%2F4H1adGLJA5CAqVlJiJ8%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=fnUeOs%2Fn%2FwnLd%2Fwj3aif4w%3D%3D.fErWs3FLveA1df60p9TQ4%2FVphWB6ZZ8PkfuUplN3jLivufuuFTlQgQk4XekPpLjo" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=v9de1xUKL6H4j7OByDydlg%3D%3D.l6i0HBktUNArYUoFEVDtUcEIDZ%2Fj3WNiim8QlhtmPVs%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=HSzWnTET%2BMsCGLVj2WHD%2Bg%3D%3D.8XDar2sB5w%2FdNhiDdLwZmKsJRg64JvF5KQu5WcjuK8dgmHtjVRq7%2FY2EgMoRNsvy6Wbl%2F1SDhE5RB8nxODc81Kq%2FrXrD1PrBh3%2FiF9hsnDs%3D" rel="nofollow">https://blog.fundebug.com/2019/04/10/fundebug-support-browser-notification/</a></p>
如何高效地遍历 MongoDB 超大集合?
https://segmentfault.com/a/1190000018595119
2019-03-21T08:48:53+08:00
2019-03-21T08:48:53+08:00
Fundebug
https://segmentfault.com/u/fundebug
18
<ul><li>GitHub 仓库:<a href="https://link.segmentfault.com/?enc=IYpYHnlfFYj1YbfZ2bQ5RA%3D%3D.l1HYw8JF9apdr25w7QGXxndHuMEbFeLn9SaCl6R0kdPnBmFLYI%2Fzg7Qv7lKrTAVQNttlLIpLOd9HmlPrGhQntQ%3D%3D" rel="nofollow">Fundebug/loop-mongodb-big-collection</a>
</li></ul>
<p><img src="/img/remote/1460000018595122?w=800&h=450" alt="" title=""></p>
<p>本文使用的编程语言是 Node.js,连接 MongoDB 的模块用的是<a href="https://link.segmentfault.com/?enc=3%2F%2Bc%2FPRzoKCMYFnGiu0dsw%3D%3D.DZ%2F6hQZaI1WOAozra7vKMUXzTGF1hnDM%2BPSfF4NCOQ8%3D" rel="nofollow">mongoose</a>。但是,本文介绍的方法适用于其他编程语言及其对应的 MongoDB 模块。</p>
<h3>错误方法:find()</h3>
<p>也许,在遍历 MongoDB 集合时,我们会这样写:</p>
<pre><code class="javascript">const Promise = require("bluebird");
function findAllMembers() {
return Member.find();
}
async function test() {
const members = await findAllMembers();
let N = 0;
await Promise.mapSeries(members, member => {
N++;
console.log(`name of the ${N}th member: ${member.name}`);
});
console.log(`loop all ${N} members success`);
}
test();</code></pre>
<p>注意,我们使用的是 Bluebird 的<a href="https://link.segmentfault.com/?enc=2hEiV5%2BPMbneHx4b9ojDQQ%3D%3D.ndlVfZNXCVdzy2EB8Qk3619zo3qUqrkAE8r25cE5Qg9CRenZSJVx4iuHaophjp8tI%2BsufxuTplQkw%2Bdy%2BJsYqw%3D%3D" rel="nofollow">mapSeries</a>而非<a href="https://link.segmentfault.com/?enc=WGi%2BmoTc%2F5feoodUa9Hihw%3D%3D.%2F2WL5VCsOOXUeejq541RuHLWDq9oTM6w%2BZz4AAjazViVmVPgpUfgapEjLYHQBZ8I" rel="nofollow">map</a>,members 数组中的元素是一个一个处理的。这样就够了吗?</p>
<p>当 Member 集合中的 document 不多时,比如只有 1000 个时,那确实没有问题。但是当 Member 集合中有 1000 万个 document 时,会发生什么呢?如下:</p>
<pre><code class="javascript"><--- Last few GCs --->
rt of marking 1770 ms) (average mu = 0.168, current mu = 0.025) finalize [5887:0x43127d0] 33672 ms: Mark-sweep 1398.3 (1425.2) -> 1398.0 (1425.7) MB, 1772.0 / 0.0 ms (+ 0.1 ms in 12 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 1775 ms) (average mu = 0.088, current mu = 0.002) finalize [5887:0x43127d0] 35172 ms: Mark-sweep 1398.5 (1425.7) -> 1398.4 (1428.7) MB, 1496.7 / 0.0 ms (average mu = 0.049, current mu = 0.002) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x8c02c0 node::Abort() [node]
2: 0x8c030c [node]
3: 0xad15de v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
4: 0xad1814 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
5: 0xebe752 [node]
6: 0xebe858 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]
7: 0xeca982 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
8: 0xecb2b4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
9: 0xecba8a v8::internal::Heap::FinalizeIncrementalMarkingIfComplete(v8::internal::GarbageCollectionReason) [node]
10: 0xecf1b7 v8::internal::IncrementalMarkingJob::Task::RunInternal() [node]
11: 0xbc1796 v8::internal::CancelableTask::Run() [node]
12: 0x935018 node::PerIsolatePlatformData::FlushForegroundTasksInternal() [node]
13: 0x9fccff [node]
14: 0xa0dbd8 [node]
15: 0x9fd63b uv_run [node]
16: 0x8ca6c5 node::Start(v8::Isolate*, node::IsolateData*, int, char const* const*, int, char const* const*) [node]
17: 0x8c945f node::Start(int, char**) [node]
18: 0x7f84b6263f45 __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
19: 0x885c55 [node]
Aborted (core dumped)</code></pre>
<p>可知,内存不足了。</p>
<p>打印<a href="https://link.segmentfault.com/?enc=3sbb1W%2BJYXCFKkOQri1tLg%3D%3D.hrmWO162EVd69q7wxqW63dgpM5mqnLSmTHG7SH1nZiLrZd4sPBDZVbPXHWBfeLw%2Fv7DosnCWNrElGnZ4HUrHHw%3D%3D" rel="nofollow">find()</a>返回的 members 数组可知,集合中所有元素都返回了,<strong>哪个数组放得下 1000 万个 Object?</strong></p>
<h3>正确方法:find().cursor()与 eachAsync()</h3>
<p>将整个集合 find()全部返回,这种操作应该避免,正确的方法应该是这样的:</p>
<pre><code class="javascript">function findAllMembersCursor() {
return Member.find().cursor();
}
async function test() {
const membersCursor = await findAllMembersCursor();
let N = 0;
await membersCursor.eachAsync(member => {
N++;
console.log(`name of the ${N}th member: ${member.name}`);
});
console.log(`loop all ${N} members success`);
}
test();</code></pre>
<p>使用<a href="https://link.segmentfault.com/?enc=%2FCUAgZO%2BK8a1R7zh5kK10Q%3D%3D.JO8Wr%2BeFvhisFARZmBFJgrDA65k%2BC7RjR2riFCd0dGUSl9va9vfqOusug6MjORn8RbH7wN6piTEW4imYqEOYKQ%3D%3D" rel="nofollow">cursor()</a>方法返回 QueryCursor,然后再使用<a href="https://link.segmentfault.com/?enc=TEhO9kfvyEAulcsRUqUkVg%3D%3D.yUqyS3AnIqS1O03R1ABCzLvhzazViuaaBwTGBBBCRkbqhjvjlS5a%2BmZ2iT1uGPAJH%2B7%2B4QseQXkewSnvf0p25oMoC4bF%2FN9EXDoTAFBPJjQ%3D" rel="nofollow">eachAsync()</a>就可以遍历整个集合了,而且不用担心内存不够。</p>
<p><a href="https://link.segmentfault.com/?enc=y4AF78dysHOc0onOLjZm1w%3D%3D.2MdmHroLaOHAEkw2XNuCaA%2BvLZgwfyRTQIhGO5kLaCvaJGAeofmyPvRW16295MaoNEDRR5x1IC0UzOctc4jLKA%3D%3D" rel="nofollow">QueryCursor</a>是什么呢?不妨看一下 mongoose 文档:</p>
<blockquote>A QueryCursor is a concurrency primitive for processing query results one document at a time. A QueryCursor fulfills the Node.js streams3 API, in addition to several other mechanisms for loading documents from MongoDB one at a time.</blockquote>
<p>总之,QueryCursor 可以每次从 MongoDB 中取一个 document,这样显然极大地减少了内存使用。</p>
<h3>如何测试?</h3>
<p>这篇博客介绍的内容很简单,但是也很容易被忽视。如果大家测试一下,印象会更加深刻一些。</p>
<p>测试代码很简单,大家可以查看<a href="https://link.segmentfault.com/?enc=bQ8c1tJBWoqdXyAkdDrSRg%3D%3D.v%2Bl13M7X8q4kLgSmAIqh8SEegRyOKx4OIOJHIlJFoIGBXDMQVHKWAqVE2J5YImvNGVC9J%2F%2F4LFJPWehPCx4Q3A%3D%3D" rel="nofollow">Fundebug/loop-mongodb-big-collection</a>。</p>
<p>我的测试环境是这样的:</p>
<ul>
<li>ubuntu 14.04</li>
<li>mongodb 3.2</li>
<li>nodejs 10.9.0</li>
</ul>
<p><strong>1. 使用 Docker 运行 MongoDB</strong></p>
<pre><code class="bash">sudo docker run --net=host -d --name mongodb daocloud.io/library/mongo:3.2</code></pre>
<p><strong>2. 使用<a href="https://link.segmentfault.com/?enc=h80jXnIUdqSOer91cPMk%2FQ%3D%3D.kVsY2H%2BnHhBsgTXCuHzvH0auj47l0wEHWaf0nBiTMCCHwqYyVIQbwHNJfQ06o44q" rel="nofollow">mgodatagen</a>生成测试数据</strong></p>
<p>使用 mgodatagen,1000 万个 document 可以在 1 分多钟生成!</p>
<p>下载 mgodatagen:<a href="https://link.segmentfault.com/?enc=n%2BQwLO8i2ynGM9ij9IXqUw%3D%3D.bS86v5te3HwHcjfIIiwIHXdGeT6PxkEVJv2sRxV0RD0t2ryt7nwGnArBlWVQ92QSMvFfj1jAgw%2BPhbqgrvYrzBHKaH2%2FoWEUUUtTbXoRhDcyjpWd6R8K8KZdHqrWCG2b" rel="nofollow">https://github.com/feliixx/mgodatagen/releases/download/0.7.3/mgodatagen_linux_x86_64.tar.gz</a></p>
<p>解压之后,复制到/usr/local/bin 目录即可:</p>
<pre><code class="bash">sudo mv mgodatagen /usr/local/bin</code></pre>
<p>mgodatagen 的配置文件<a href="https://link.segmentfault.com/?enc=o40m4iRrUC64l9H8LWGP8g%3D%3D.cgAgj4vyd84jrO0qZo%2Bh61rwimhv0afrSbv6yMwBrk09mr9uWBL%2F9sV2fx4tQ8%2FWBkfxjfte%2FL5FXuNzXO8q907stHMPx8K4azx7dx0EW1Apzp0glBKc798qT9%2FIAKRT" rel="nofollow">mgodatagen-config.json</a>如下:</p>
<pre><code class="json">[
{
"database": "test",
"collection": "members",
"count": 10000000,
"content": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 8
},
"city": {
"type": "string",
"minLength": 2,
"maxLength": 8
},
"country": {
"type": "string",
"minLength": 2,
"maxLength": 8
},
"company": {
"type": "string",
"minLength": 2,
"maxLength": 8
},
"email": {
"type": "string",
"minLength": 2,
"maxLength": 8
}
}
}
]</code></pre>
<p>执行<code>mgodatagen -f mgodatagen-config.json</code>命令,即可生成 10000 万测试数据。</p>
<pre><code class="bash">mgodatagen -f mgodatagen-config.json
Connecting to mongodb://127.0.0.1:27017
MongoDB server version 3.2.13
collection members: done [====================================================================] 100%
+------------+----------+-----------------+----------------+
| COLLECTION | COUNT | AVG OBJECT SIZE | INDEXES |
+------------+----------+-----------------+----------------+
| members | 10000000 | 108 | _id_ 95368 kB |
+------------+----------+-----------------+----------------+
run finished in 1m12.82s</code></pre>
<p>查看 MongoDB,可知新生成的数据有 0.69GB,其实很小,但是使用 find()方法遍历会报错。</p>
<pre><code class="bash">show dbs
local 0.000GB
test 0.690GB</code></pre>
<p><strong>3. 执行测试代码</strong></p>
<p>两种不同遍历方法的代码分别位于<a href="https://link.segmentfault.com/?enc=xtViXpukWKdLXXPTYNb1RA%3D%3D.CSntlcWIaN2GRyphR5k4zrPhz%2B9id3bbM%2BERrzRrq2ynIpPvZc19BiBrQ%2BADFMJeGQHKhfORQggv%2BllEc79xVp90%2FHf5wibbagaZvvYZsoI%3D" rel="nofollow">test1.js</a>和<a href="https://link.segmentfault.com/?enc=fTVZPJGOJqeLG7XXgOkf1A%3D%3D.ocChHh2I1zJ7Y20Rl%2F%2Fd2GnwlYaxO%2B%2FzLbVe3pX7H%2BzI9m2J0Gj4I%2FXxdqxWvxAXdnMfG5wKSGkE9zB2TRYuHf7%2BA5EY1q7z8H4RJOi2378%3D" rel="nofollow">test2.js</a>。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=vp2lQrP91ALulscGIN9vTQ%3D%3D.FQ57cFCfwIrwwc90m8wy%2BzLa%2Buremju0bBAtlMQGCqhevG2Siagl9HbaWxOpSEBpBdJQT377L4me%2BSwW8C94uQ%3D%3D" rel="nofollow">如何使用 mongoose 对一个 100 万+的 mongodb 的表进行遍历操作</a></li>
<li><a href="https://link.segmentfault.com/?enc=61MPSPXk%2F7yX4I3JwQvbyg%3D%3D.PFE0joy9OznlNT9iEc8EhzXgxHxJjw8l7IXRiscfDkYdeDGvM%2FwAY9x02Tg4Z4Udgt%2FSAwTrgs6tYh%2BLmUzuQA%3D%3D" rel="nofollow">Cursors in Mongoose 4.5</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=cZSmn0%2FLLdBdiAxmJ3BWfA%3D%3D.z35eRg5aPGjWswhG06oSSvs5SPjwiQV9uSUDeB9ykBc%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=9XyurNoW1n71uV2KMomGgQ%3D%3D.gLQesGJ2Iifqr1xRivuuzYXID4EIRiGTCuDULS3j%2BWT4lkmBD9LsRuPEiI05LLoL" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=YBYRoDT6jT4RkYdHmRSiEw%3D%3D.5M23p2NX3TeeCOUJYr%2FhfvvoVQmQB4oFbq%2FmUjffCpc%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=ORCDic0kbZfYAiDPOZfPIg%3D%3D.TcUn7Qf6ITTyMx2oem%2BsPuDNJRT33wZB%2BjdI6wz2H2d9%2B9tVC%2FxA%2F4DBG7C9nsDiZwGOeInXkkveS%2FxfEMQ6Xja6FWnoeUzrw9YvDHW8wykGSNVmNyfQKu1xTcr%2Bdx3g" rel="nofollow">https://blog.fundebug.com/2019/03/21/how-to-visit-all-documents-in-a-big-collection-of-mongodb/</a></p>
不要争了!技术选择没那么重要
https://segmentfault.com/a/1190000018569316
2019-03-19T11:23:37+08:00
2019-03-19T11:23:37+08:00
Fundebug
https://segmentfault.com/u/fundebug
10
<p><strong>摘要:</strong> 技术没有高下之分,做好产品才是王道。</p>
<p><img src="/img/remote/1460000018569319?w=800&h=450" alt="" title=""></p>
<p>很多开发者非常热衷于比较不同技术,比如:Angular 是否比 Vue.js 更好?Node.js 能否取代 Java?究竟应该选择 MySQL 还是 MongoDB 呢?</p>
<p>认真对比不同技术之间的优劣是非常有价值的事,可以加深我们对技术的理解,根据业务场景选择<strong>更合适的技术</strong>。</p>
<p>但是,对技术选择过于较真,争得面红耳赤,对于产品或者个人来讲,都是没有必要的。因为,<strong>技术选择真的没有那么重要</strong>。</p>
<h3>技术只是产品的实现手段</h3>
<p>对于一个产品,技术仅仅只是实现手段。或者说,条条大路通罗马,这个产品可以用 Angular + Java + MySQL 实现,那它用 Vue.js + Node.js + MongoDB 来实现也完全没问题。不同技术在细节上确实有不少区别,但是它们在本质上它们是一样的,Angular 和 Vue.js 是前端框架,Java 和 Node.js 是编程语言,MySQL 和 MongoDB 是数据库。</p>
<p>产品面向的是用户,而不是开发者自己,在开发者开来,选择某个技术栈也许很重要,但是对于用户来说,很抱歉,他们<strong>完全不关心</strong>!用户关心的是:是否有我想要的功能?UI 设计是否合理?BUG 有没有及时修复?生活中,我们都是用户,我们每天聊微信、刷抖音、逛京东、打王者荣耀,你会关心它们的后台是用 Java 还是用 Node.js 吗?</p>
<p>如果产品的技术栈还没有确定,选择一个<strong>目前使用者足够多并且保持更新的技术</strong>就好了,用的人多的技术不会太差,还在更新则不用担心 BUG 没人修复。如果产品的技术栈已经确定了,那就更简单了,直接撸代码啊;即使技术选择有一些问题,抱怨是没有用的,也没人愿意为了你的个人偏好去换技术栈,除非是产品需要。</p>
<p>作为开发者,应该利用自己已经掌握和需要学习的技术去实现一个好用的产品,满足用户的需求。如果产品没有成功,有可能是产品的需求有问题,没有市场;有可能市场很大,但是推广得不够成功;有可能推广得不错,但是商业模式有问题,赚不到钱...当然,也有可能是技术问题,是技术不够好,而不太可能是技术选择错了。</p>
<h3>Fundebug 的技术栈</h3>
<p>当我们决定做<a href="https://link.segmentfault.com/?enc=jlAzL5mdntkCGL7BF7ms5g%3D%3D.vuQ7XN8Y7FbZx2m%2BH6lB6guv8bQ8RC77T0IGoRPM%2F0w%3D" rel="nofollow">Fundebug</a>的时候,现在所使用的技术并不熟悉,而对于它们的同类型技术,我们更是一无所知。所以,这里也不存在所谓的选择的问题,我们使用了自己会用的技术:Angular + Node.js + MongoDB。它们<strong>使用者足够多并且保持更新</strong>,符合我所说的标准。对于这样的似乎有些<strong>轻率</strong>技术选择,基本上没有对我们产品开发造成什么困恼,用户需要的功能我们能够尽量满足。或者说,正真困恼我们的从来都不是技术选择所造成的问题,而是<strong>产品设计、市场推广、用户沟通</strong>等问题。</p>
<p>我会负责一些后端开发,对于我们的技术栈,我热爱 Node.js,因为它语法简洁,文档清晰、有着简单的异步编程模式和丰富的 NPM 生态系统;我也很喜欢 MongoDB, 因为它的数据模型足够灵活,然后文档非常详细,运维起来轻松很多。这里没有丝毫冒犯 Java 和 MySQL 的意思,因为我几乎完全没有接触过它们,所以无法进行比较。我也相信,Java 和 MySQL 也非常优秀,如果我们当初选择它们应该也没有什么问题。</p>
<p>对于 Fundebug 的技术栈,我经常喜欢和人炫(chui)耀(niu)的一点是<strong>我们的所有应用包括 MongoDB 都是运行在 Docker 容器里面,这极大的简化了我们的运维工作</strong>。把应用打包到 Docker 镜像里面之后,我们只需要在集群上安装 Docker,而不需要安装任何应用,就可以在任意节点运行任意应用。我们可以根据需要(重新分配 CPU 和内存资源或者进行多副本扩容)随时在任意节点之间移动应用。在集群需要增加新的节点时,也只需要安装 Docker,这个新节点可以用来运行任何应用。我一直在思考 Docker 的价值,发现它确实很有用。所谓<strong>“如果你手里有一把锤子,所有东西看上去都像钉子”</strong>,我用了将近 4 年 Docker,非常熟悉也非常喜欢,那我当然觉得 Docker 是个好东西。如果我们不使用 Docker 会怎样?运维当然会比较痛苦,但是我们应该也没有什么大问题。大量公司还没有 Docker 化,它们都活着好好的。</p>
<h3>我对技术的迷思</h3>
<p>和很多开发者,我也曾经迷信过一些技术,谁没年轻过呢?</p>
<p>大三暑假学了一门叫做<a href="https://link.segmentfault.com/?enc=1IjPRC3%2BXqZQvZTHs3HRgw%3D%3D.Urhhfl02ezPEZX3yyYvpUbG4mCYcfTs4e8%2B4Ut7RMNrrubrWbo5ZjFbFgZIx4q2y" rel="nofollow">《大规模数据处理/云计算》</a>的课,听着很炫酷,其实主要是学习 Hadoop,用 Hadoop 去实现 PageRank 等算法。PageRank 是 Google 创始人提出的网页排序算法,是 Google 搜索引擎的基础。Hadoop 如此厉害,居然可以造 Google,当时年少无知,觉得学会了 Hadoop 就够了。事实上,知乎上也有类似的问题:<a href="https://link.segmentfault.com/?enc=ndVS3fv4chDqchLhOuBFnw%3D%3D.PR3aoD3uQeAHcX7CZI1DJMOzfcEeYo%2B7gu9JM8zNlnolJUW4l7bMWrAi4cJ1ElFy" rel="nofollow">Hadoop 就业前景如何?</a>但是,现在呢?Hadoop 的光环早已褪去,它只不过是对大规模数据进行批处理的常规工具,并没有太大门槛。而 Hadoop 生态系统还有很多其他工具比如 Spark, HBase 等,仅仅使用 Hadoop 完全不足以应对各种复杂业务场景。</p>
<p>读研的时候第一次接触 Docker,被深深吸引,因为 Docker 可以完美解决软件安装和配置的问题。大学毕业设计我曾花了至少 1 个星期时间配置一个 4 个实体机器组成的 Hadoop 集群(当时不熟悉 Linux),而使用 Docker 的话,无需安装,可以直接运行。我的开源项目<a href="https://link.segmentfault.com/?enc=NM5wIGkoQ5U%2Fs3VdK68U5g%3D%3D.%2FVa0WGwv9NBUPRDhCJHMvRsHKgi3yt24hmIg5E0Q55FSSyVXrQ9TIMlb84Rq9h%2Few6RkMnXmgfF2Vevq20ihGg%3D%3D" rel="nofollow">hadoop-cluster-docker</a>就是将 Hadoop 集群运行到多个 Docker 容器中,这个项目已经累积了近千个 Star,可见大家对于使用 Docker 简化 Hadoop 安装还是非常认可的。我接触 Docker 的时间算是很早了,Docker 最热门的时候还收到过大公司的相关工作邀请,因此觉得熟悉 Docker 非常好,这次算是站在风口了。而现在呢?Docker 已经逐渐普及化!因为 Docker 并没有什么高深之处,上手非常快。国内很多大公司,例如<a href="https://link.segmentfault.com/?enc=pb1Mgl0j2zKTngMsPJtDSA%3D%3D.rGx1QEF%2FFvlyh3fp8vgV6lENJpTVGS8YMrWYk1R24A5x6Mq%2BLgJLmQm6nFMKG0VIAwvobYrzEb5JhNz%2FVhNgeVgckp3u9nqpjmzvbCqRsXdclBhDpbB%2F1yiKFmzR0jhh" rel="nofollow">腾讯</a>, <a href="https://link.segmentfault.com/?enc=gA3NzGT3xBrlX4fswx%2BJFQ%3D%3D.qh1PRfwqmlaspKkt%2Fv31xo3oiS%2BBnbCpTs8wPQT5OKgCeJxca8X7KynOiMiFTpMLSK5GFFx%2Fe1djMjf2C4XP3Eh1erapS4VPHKEwojjwE1g%3D" rel="nofollow">京东</a>等早已 Docker 化。</p>
<p>无论是 Hadoop 和 Docker,多少都算是改变世界的技术,也曾经大红大紫,现在依然在发光发热,但是早已不再自带光环效应。这也是技术发展的客观规律,新的技术不断出现,它们解决了某些问题,受到热捧,然后逐渐普及,被更新的技术所超越甚至取代。</p>
<p>事实上,我从来也没有依靠 Hadoop 或者 Docker 去工作,它们也是靠不住的。技术发展如此之快,怎么可能一招鲜吃遍天,现在热门的技术迟早会冷却,甚至会被淘汰。再说,技术是为工作服务的,而不是围绕技术栈去圈定自己的工作内容;工作的时候,需要什么技术就学习什么技术,永远呆在舒适区是一件很危险的事情。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=o095a4iIqZUpKpXa%2F0EGHg%3D%3D.ZsLHkgoyNIej4cUSWsqGDE3Fef3UscXIFjost%2Fsf4S44iwvWmHss7hNdf68yOoTWOOHm2qbEydqG%2B1qQ2Cog2g%3D%3D" rel="nofollow">技术路线的选择重要但不具有决定性</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=yQ3CtEZ00C7eprSl27w%2BEA%3D%3D.dLBBKh%2B13kHG9M2X6R%2BeARnmZKuwVWOIDXC90SBVQJM%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=FxtsLHzdqdh00oxMaVLOPw%3D%3D.YcMLq1E%2B82p7lexgnxit7z8sF8WQAXdvdbWv%2BvTM%2FM4xCFKz0Cw425oWppn%2FoebT" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=zRgaXf%2FMp0HI46reRYUmag%3D%3D.Zrxg%2FxKehY%2B7m%2Fvye%2BVSlDaq4zwSu1GWFnTSZZ0H3iw%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=tMI27el9cD%2B%2FYdbIvzCSMA%3D%3D.4zYuZ%2BBBsa73WSa%2FlGn0Niu7gB2axKnCEQCxwk6hOs7gAVDDdbI2Lp2fGwFgXU1XDy6pfkrrNJh26fGCFqvfEvY2BC71UhpeuSGm%2FoqfUzY%3D" rel="nofollow">https://blog.fundebug.com/2018/07/19/technology-selection-is-not-critical/</a></p>
Fundebug前端JavaScript插件更新至1.7.1,拆分录屏代码,还原部分Script error.
https://segmentfault.com/a/1190000018471557
2019-03-12T11:15:31+08:00
2019-03-12T11:15:31+08:00
Fundebug
https://segmentfault.com/u/fundebug
10
<p><strong>摘要:</strong> BUG监控插件压缩至18K。</p>
<p><img src="/img/bVbpIPC?w=900&h=383" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>1.7.1</strong>拆分了录屏代码,BUG监控插件压缩至<strong>18K</strong>,另外我们还原了部分Script error,帮助用户更方便地Debug。请大家及时更新哈~</p>
<h3>拆分录屏代码</h3>
<p>从<strong>1.7.1</strong>版本开始,我们拆分了录屏代码。如果需要使用录屏功能的话,需要单独接入录屏插件。</p>
<p><strong>使用script方式接入</strong></p>
<pre><code class="html"><script type="text/javascript" src="https://js.fundebug.cn/fundebug.revideo.0.2.0.min.js" ></script></code></pre>
<p><strong>使用NPM方式接入</strong></p>
<pre><code class="javascript">require("fundebug-revideo");</code></pre>
<h3>还原部分Script error.</h3>
<p>关于Script error.的原理以及解法的详细介绍,请参考我们的博客:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=WywuwTJLDTucZrFCVWNONg%3D%3D.wI2ody10p4qdJhAmsdxvoayO0qFkuCszVHj%2FG3Yvl7Pe8ITlFWPUsIEpj%2FH2ic3IJp4FtCIi0HGR5vmj6VUGwA%3D%3D" rel="nofollow">Script error.全面解析</a></li>
<li><a href="https://link.segmentfault.com/?enc=0TjNh10JFV9OEtx2WWTt0g%3D%3D.DEdHxM98wJv8aYPPP54zy3sYfXIn74T23JQdutG8p0yMhHB2%2BdwiqlUq2IjGIeij6r2WQibd1kPRquPqeHI6DQ%3D%3D" rel="nofollow">Script error.深度测试</a></li>
<li><a href="https://link.segmentfault.com/?enc=3o%2Fmi1jot3LjeF0UlRz7rw%3D%3D.Sw8Od9SC%2BC8C7qii9Rqj9hDCLzqSsCH6MuYG718MSgqOY72JwYm%2FhdkY9yrSeV3Gn3o3J1ZkA4LR3jcf1Xgn3g%3D%3D" rel="nofollow">Script error.解决方法</a></li>
</ul>
<p>简单地说,当跨域的JS脚本出错时,浏览器为了安全性,只会给我们返回"Script error.",这样会对Debug造成很大困扰。</p>
<p>我们通过技术手段,成功还原了addEventListener回调函数中抛出的Script error.</p>
<p>感兴趣的同学可以将下面这段代码放到跨域的JS脚本中进行测试,Fundebug插件1.6.0只能获取Script error,而1.7.1则可以成功获取真实的报错信息"test"。</p>
<pre><code class="javascript">var btn = document.querySelector("#button");
btn.addEventListener("click", function() {
throw new Error("test");
});</code></pre>
<p>最后,感谢Fundebug用户<strong>yaoqi</strong>与<strong>penyu</strong>的反馈!</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=ryDVknqaUyS2pwGpNH8L6A%3D%3D.BCpgEEEVTsuOTDNqx6ASqCiWIY2Exs5enQhTpKadkSgD%2FyXMEthi25XFXN%2BrHHvISy98rV9k7uQ%2BLm0L53q8Xss59c83A85nwnHU0JKTlkA%3D" rel="nofollow">黑科技!Fundebug支持可视化重现出错场景</a></li>
<li><a href="https://link.segmentfault.com/?enc=ckcp4vXz8JQ2qE2jiz%2FGNQ%3D%3D.RCGIDf3%2FhAR0V4xmgEahr2mkVebWc6vnV7CkLpmw8pRSPlGzIqTKfhR3A08mw0nEyfNJY1JIoLnVK%2BKaA%2B%2BIkg%3D%3D" rel="nofollow">Fundebug文档 - 录屏</a></li>
<li><a href="https://link.segmentfault.com/?enc=dKhyyu%2FloXfCATp0IxhcIg%3D%3D.kZjzO8greqYXSrAqxhuEiKGy9VZqXHbZMDCZiFjhOXMvZoLd1I0%2Bjfn3lCqF2XfeeRQm%2FrC2NO6uusIrvxrlTw%3D%3D" rel="nofollow">Script error.全面解析</a></li>
<li><a href="https://link.segmentfault.com/?enc=QcYW7ZNBbOnCtH1ue%2Booaw%3D%3D.WuoyVoCkJ40QW1oYhsHPVxgoHLiunG4uc5TGTt2O%2FFHLNptrUkttq2Kyz9Fhc6UNTSKns8HTzzlXV%2FPRVe6y4w%3D%3D" rel="nofollow">Script error.深度测试</a></li>
<li><a href="https://link.segmentfault.com/?enc=rEYnCVBzZI6Js6Jh%2Byl89Q%3D%3D.RteaC6qs76TaI6790PY64aFgQ44xhGKsXIyyX1H78GGNCiMRrWHwMEG9A7tQ6RlKvNgzVSp33L22B%2BI5K6JpdQ%3D%3D" rel="nofollow">Script error.解决方法</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=xujFnpdrX%2FGKWuIloAmPug%3D%3D.i%2FxZDvfxzcAyNY7djWYbqeCVEh0gJMFsMoa9L2EqboQ%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=Rv6FdKBqNY%2FqckzufVaUnA%3D%3D.nrx9%2BJs7lthTZ2jSpXXFm%2FGcYZESLykjdYsYAinHCjiRd7LAn%2B3VYY%2FEvOccl7zl" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=H346sALOK4Aiq55AkIlteQ%3D%3D.QPzuWsxeGyhaeEgr03T42OXAUabQfjcXgHoCVqMeQOA%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=l5AocOd8IIykz3Pu8wr%2BBg%3D%3D.mgQk8CQzoWBLLjtgWMSNgxAIf7hVY%2BydZ0DwXlAzYuCACSycewC0jm09sh3qCRaqJZBZqHH%2Fz641s4Hfp672Ew%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/03/11/fundebug-javascript-1-7-0/</a></p>
我们应该如何给需求排序?
https://segmentfault.com/a/1190000018389457
2019-03-05T10:23:55+08:00
2019-03-05T10:23:55+08:00
Fundebug
https://segmentfault.com/u/fundebug
4
<p><strong>摘要:</strong> 需求管理是一门艺术。</p>
<p><img src="/img/remote/1460000018389460?w=900&h=383" alt="" title=""></p>
<p>开发产品的时候,我们每天都会面对各种各样、没完没了的需求,有的来自外部用户的反馈,有的来自内部团队的idea,有的是产品的BUG,有的是新的功能...</p>
<p>看起来只要实现所有需求,产品就可以变得更好,然后吸引更多的用户,接着赚更多的钱,之后招更多的人,再完成更多的需求...</p>
<p>问题是,需求会源源不断地进来,我们永远也不可能清空所有需求,996也做不完,这辈子都不可能。</p>
<p>我们能做的,是不断将需求排序,实现优先级最高的需求。那么问题来了,<strong>我们应该如何给需求排序?</strong></p>
<h3>以用户为核心确定优先级</h3>
<p>乔布斯曾经说过:</p>
<blockquote>People don't know what they want until you show it to them.</blockquote>
<p>用户真的不知道他们想要什么吗?很多时候并非如此。</p>
<p>我负责产品,<strong>每天都会和用户交流</strong>,他们知道自己想要什么功能,有时会做好简单的交互设计、帮忙想想算法、甚至给我开源代码。</p>
<p>问题在于,用户只是产品的使用者,他们对于产品的理解没有我们那么深刻,所以他们提出的需求有时会偏离问题的本质,需要我们进一步分析与挖掘。</p>
<p>我们不是乔布斯,没有能力创造需求;我们也不是张小龙,没有1亿人教我们做产品。因此,我们应该多与用户交流,以用户需求为核心确定优先级:</p>
<ul>
<li>用户反馈或者吐槽的时候,耐心一些,聊得更深入一些,同时做好记录</li>
<li>修复BUG,优化功能或者新增功能时,与感兴趣的用户主动联系,他们会给你更多的反馈</li>
<li>定期做用户调研,听听沉默的大多数是怎么说的</li>
<li>对于用户所提的需求,根据反馈用户多少、影响范围、难易程度进行排序</li>
</ul>
<p>当我们做产品的时候,创造的欲望是非常惊人的,总会有一些新的idea让我们激动不已,恨不得明天就能上线。但是,我们应该克制自己的创造欲,尊重用户的意见。我们的产品是给客户用的,不是给自己玩的。</p>
<p>流量红利已经枯竭的时代,获取一个新用户比留住一个老用户难太多了,因此提高留存率显得非常重要。重视每一个用户反馈,及时修复他们发现的BUG,优先实现他们想要的功能,是提高留存率最有效的方式,没有之一。</p>
<h3>BUG的优先级高于新功能</h3>
<p>墨菲定律是这样的:</p>
<blockquote>Anything that can go wrong will go wrong.</blockquote>
<p>程序员应该都知道,<strong>代码怎么可能没有BUG呢?</strong>很多时候只是我们没有发现,或者是知道了却没有及时修复。</p>
<p>然而,对于当前产品的BUG,我们往往容易忽视。可能是BUG隐藏的太深,我们和用户都没有发现;可能是用户发现BUG,但是没有反馈;也可能是我们选择性失明,觉得问题不大。</p>
<p>事实上,用户对产品质量的要求非常严格,再小的问题他们也会发现,也会吐槽。用户反馈的话我们还能知道,否则我们可能很晚才发现BUG,如果没有监控的话。</p>
<p>还有一种微妙的情况,当用户反馈貌似不可能出现的BUG时,我们会本能的觉得产品应该没有问题,问题应该出在用户那里,大概是他的浏览器或者网络,或者某种无法解释的原因导致的。其实,这只是我们在逃避问题,代码的运行方式是确定的,没有什么不能解释的地方,如果什么地方不太对劲了,那基本上是BUG。这里分享一个我们的经历:</p>
<blockquote>某个用户反馈,他在邀请成员加入团队的时候发现,偶尔会有那么一次邀请失败。<br>我们检查了一下监控数据,发现确实有失败过,影响的用户不止一个,但是很少。<br>然后,我们检查了一下前后端代码,发现没有问题。<br>既然业务代码没有问题,那应该没有BUG,这事大概是什么奇怪的原因导致的,我们什么也不用做吧...<br>后来,又有几个用户反馈同一个问题,报错也越来来越多,我们不可能再骗自己了!<br>再次检查,业务代码确实没有问题,但是报错的代码位置的行号和列号都偏移了,这么诡异?<br>不难猜测,生产环境运行的是旧代码!检查一下果然是这样。<br>接着,不难发现部署的Docker配置文件有问题,导致某个节点部署的后端代码是旧的...</blockquote>
<p>我们总是这样,不停地向前走,不断地追求新的成就,逃避当下的问题。<strong>听着是不是很像我们的生活?</strong></p>
<p>对于产品BUG,我们应该第一时间修复,或者设置一个Deadline,新的功能可以稍微延后。</p>
<p>如果我们不停地开发新功能,那当初开发这个有BUG的旧功能究竟是为了什么?如果我们忽略当前用户反馈的问题,那我们费这么大劲拉新是为了什么?</p>
<h3>结论</h3>
<p>需求管理是一门艺术,需要考虑和权衡的东西很多,暂时给大家一个简单的优先级排序,仅供参考:</p>
<ul>
<li>用户反馈的BUG</li>
<li>自己发现的BUG</li>
<li>用户反馈的需求</li>
<li>自己想出的需求</li>
</ul>
<p>严格按照这个顺序操作是不可能的,这是给大家提供2个思考维度。实际工作中,每个需求的影响范围、紧急程度、难易程度也需要考虑。</p>
<p>你有什么更好的想法吗?欢迎留言讨论!本文作者为Fundebug的技术总监,欢迎添加微信交流:KiwenLau。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=XZX9zL0yMDWN6YE6rdq3UA%3D%3D.V0r%2FMCxI6hiigBzn8dhXnuLp9B7iHqCN9Fwcus1e2opi6URv2y1Kv3ORkcmkKvJ2nLyf0Qion0AS8TKPkgtuvQ%3D%3D" rel="nofollow">产品需求优先级的艺术 -- Kano模型</a></li>
<li><a href="https://link.segmentfault.com/?enc=CCaMBKcppv%2BVUz2Vdf4Y1Q%3D%3D.GHhXjFS3bzwbkeDJ67oN7hzJee0%2F7PMlmvqdI5690eUSt9Ywniia3doq9YRJPN9dr%2F%2BE0bzz1wBKy%2FScn2XpzQ%3D%3D" rel="nofollow">如何成为优秀的技术主管?你要做到这三点</a></li>
<li><a href="https://link.segmentfault.com/?enc=TD4Frs3FfgkL2txk%2BXBG2Q%3D%3D.E4ybDkTqbMi%2B%2BfSq1XdTHdHkW%2B8KPowP7DGB7JT1bnpUTf7xsDRKBEtUaIJzkcOoKok4XXeSBzqhB6wUJwQ0iQ%3D%3D" rel="nofollow">为什么美国程序员工作比中国程序员工作轻松、加班少?</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=GZfnSTOdgRuhQ9UUyJA5rw%3D%3D.m0b8cUEQX%2FAg%2Ffc%2FIKVss089leNx8UfLjSD7CW40voI%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=rVfCjIq3JjJnJ0O5IXjWgQ%3D%3D.dPDcFSb3Ms9LmBq83AqxJCmZE1KfABoM3S0CDbmHzz5dyIgmggVPNW8mYgPYa4zz" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
Fundebug计费标准解释:事件数是如何定义的?
https://segmentfault.com/a/1190000018349609
2019-03-01T09:31:23+08:00
2019-03-01T09:31:23+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 一个事件指上报一次报错数据,同一个错误重复上报将重复计算事件数。</p>
<p>一些新用户对于<a href="https://link.segmentfault.com/?enc=NHU2d%2B0nVztgHWjbDIVOjQ%3D%3D.1mt%2BeviNxlcr3XHjWtKF8IIS2umQS%2FWOgai4MT3PxCU%3D" rel="nofollow">Fundebug</a>的计费标准有所疑惑,这里给大家解释一下。</p>
<h3>Fundebug付费套餐</h3>
<p><a href="https://link.segmentfault.com/?enc=00b0joRcyVAH%2BnyQnOnLpw%3D%3D.uq2bRu6ZZbDP5by4Aqp59eEUYIXGIS%2B34sdtnrqwtJQ%3D" rel="nofollow">Fundebug</a>提供了多个不同档位的付费套餐,其主要收费标准是按照<strong>事件数</strong>来确定的。当前<a href="https://link.segmentfault.com/?enc=hKWtG6jpcnuQVb6AJY1%2BlQ%3D%3D.VPfnoxb6QL6HYRxWpFHM5oaot%2FEx2wqPlyAanBhuJ54%3D" rel="nofollow">Fundebug</a>各个付费套餐每月的事件数及其价格如下表:</p>
<table>
<thead><tr>
<th><strong>事件数</strong></th>
<th><strong>价格</strong></th>
</tr></thead>
<tbody>
<tr>
<td>0.3w</td>
<td>0</td>
</tr>
<tr>
<td>5w</td>
<td>59</td>
</tr>
<tr>
<td>15w</td>
<td>159</td>
</tr>
<tr>
<td>45w</td>
<td>359</td>
</tr>
<tr>
<td>150w</td>
<td>859</td>
</tr>
<tr>
<td>450w</td>
<td>2559</td>
</tr>
<tr>
<td>1500w</td>
<td>6559</td>
</tr>
</tbody>
</table>
<p>例如,月费用为359的付费套餐每个月的事件数额度为45万。</p>
<h3>事件数是什么?</h3>
<p>简单地说,<strong>一个事件指的是上报一次报错数据</strong>。以前端应用为例,每次调用<a href="https://link.segmentfault.com/?enc=ibynthh%2BoEmepqk7ksXD7g%3D%3D.BLUVDIs8gvRdIe7dhx%2F7ROY8%2FzjUw%2FaqXB7GTmkZIujEZqjwBLdkkvdhv5qNk9%2Bz7wjSBWe3UNKAw0MsFaStmQ%3D%3D" rel="nofollow">fundebug.test()</a>都会上报一次错误数据,则算作一个事件。</p>
<p>另外,<strong>同一个错误重复上报将会重复计算事件数</strong>。同一处代码BUG,在不同设备、不同浏览器、不同页面的报错事件的数据细节会有所不同,<a href="https://link.segmentfault.com/?enc=8CYYKXzOKzDLA%2FIw5MyUbQ%3D%3D.IyOSQfB4oN3a9Jaq1BYjj2%2F5N0eDJDa8kEUGLlg2V3k%3D" rel="nofollow">Fundebug</a>可以将这些事件智能聚合为同一个错误。但是,我们是按照事件数而不是错误数计费的。例如,当某个错误重复出现了1000次时,则事件数则为1000。</p>
<h3>事件数超量了怎么办?</h3>
<p>如果您的事件数超量了,<a href="https://link.segmentfault.com/?enc=dw7SS8uTaawpRSGqblRPyQ%3D%3D.uZxhkGRPCiEG9iRpgFkBz7VnZpWheHNFU4wIBkau5ZQ%3D" rel="nofollow">Fundebug</a>将不再存储新上报的报错事件,这意味着您无法看到最新的报错,影响您对产品质量的把控。这时,建议您及时升级付费套餐。</p>
<p>另外,您也可以通过配置过滤器filters来过滤掉无需上报的错误,或者通过配置sampleRate进行采样,这样可以有效减少上报数据量。</p>
<p>最后,感谢所有用户对<a href="https://link.segmentfault.com/?enc=%2FgYje8AKLGJsAx43eN8W7Q%3D%3D.teVJWhXU3AWYqhG7%2BtS7nkfMDe%2BMK3o6vuGobb3n%2FYM%3D" rel="nofollow">Fundebug</a>支持。</p>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=x65bjJAt5ukzzvQtjaUDng%3D%3D.JQCop4ETWhfuLAS5YsmnNE74Fo9E8Em6AFHD6hSX9LY%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=OCuTxycVZMIj5zMzgRI9dQ%3D%3D.JSglXH9W2QfLpeL46tSiroB0j9bJRpKMI3Xky96rz097fsTjIgXX8EwSb6UjHmby" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=tmJSvbz3I2sC2WT6QGvMtQ%3D%3D.Y%2BB%2FW2OFN%2BOFnkUkNsgnYMHk1PG13cOuSxZEwTbgz%2BU%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=Mv6FHR5IZMn7v2KRiHqvGQ%3D%3D.PidB2x%2FzRnldjVSJ%2Fg0szaZWgS0LI6sNDmDn0KtkeWGk0mcftDXGP%2FY4lm5%2FE%2FkZSTOOTvs4MqwpphJqgpbCc1ijrXLuty1zjlqF8v%2FLQvE%3D" rel="nofollow">https://blog.fundebug.com/2019/02/28/what-is-event-number-when-use-fundebug/</a></p>
import提升导致Fundebug报错:“请配置apikey”
https://segmentfault.com/a/1190000018336727
2019-02-28T11:27:37+08:00
2019-02-28T11:27:37+08:00
Fundebug
https://segmentfault.com/u/fundebug
1
<p><strong>摘要:</strong> 解释一下“请配置apikey”报错的原因。</p>
<p>部分Fundebug用户使用import来导入js文件时,出现了"请配置apikey"的报错,这是由于import提升导致的,下面我会详细解释一下这一点。</p>
<h3>import提升</h3>
<p>关于import提升,我们可以参考阮一峰的<a href="https://link.segmentfault.com/?enc=witaPcjPOnLj3iAccv1xuA%3D%3D.oYM%2B04sTbsPsp6XCKUdJGjbPIXcV1UrpcDDIDcbfMjE%3D" rel="nofollow">《ECMAScript 6 入门》</a>。</p>
<p>import命令具有提升效果,会提升到整个模块的头部,首先执行。</p>
<pre><code class="javascript">foo();
import { foo } from 'my_module';</code></pre>
<p>上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。</p>
<p>因此,<strong>即使我们把import语句写在后面,它仍然会在其他语句之前执行</strong>。</p>
<h3>import提升为何导致Fundebug报错?</h3>
<p><a href="https://link.segmentfault.com/?enc=kSI%2FK%2BnZYV4QBBiQnT2iaQ%3D%3D.vQnW3%2FP0z9iawFcf7GzAooJzeNrGh9EglqtDmEsLNiI%3D" rel="nofollow">Fundebug</a>用户应该清楚,在接入<a href="https://link.segmentfault.com/?enc=htWWBHLORm4Mc1sgJFmObQ%3D%3D.mF61Mg9fRGrB2FgD1ngRJi6V1LKGHxWpDR%2FieiXo%2BA3ATkx7o6mXxyit08L19pKVTmdL0rrZRLMxouw4tWnBFQ%3D%3D" rel="nofollow">fundebug-javascript</a>插件之后,需要配置apikey,如下:</p>
<pre><code class="javascript">import * as fundebug from "fundebug-javascript";
fundebug.apikey = "API-KEY";</code></pre>
<p>假设我们还需要import一个<strong>test.js</strong>文件,这个文件会抛出一个Error,如下:</p>
<pre><code class="javascript">// test.js
throw new Error("test")</code></pre>
<p>一切看起来没有问题:</p>
<pre><code class="javascript">// main.js
import * as fundebug from "fundebug-javascript";
fundebug.apikey = "API-KEY";
import "./test"</code></pre>
<p>但是,根据import提升,代码的实际执行顺序如下:</p>
<pre><code class="javascript">// main.js
import * as fundebug from "fundebug-javascript";
import "./test"
fundebug.apikey = "API-KEY";</code></pre>
<p>这种情况下,第二行代码就会抛出错误,导致apikey复制语句不会执行,从而导致报错:“请配置apikey”。</p>
<h3>这个问题并不需要解决</h3>
<p>出于测试的目的,用户会去import一个立即报错的js文件,类似于前文提到的test.js。但是实际开发中,我们不可能这样做,否则应用会立即崩溃,更谈不上部署了。</p>
<p>我们写这篇博客的目的仅仅是解释一下原因,并分享一个非常简单的知识点“import提升”。</p>
<h3>如何规避这个问题?</h3>
<p><strong>仅供参考,实际上没有必要这样做。</strong></p>
<p>新建一个配置文件<strong>config.js</strong>,在这个文件中配置apikey:</p>
<pre><code class="javascript">fundebug.apikey = "API-KEY";</code></pre>
<p>import配置文件:</p>
<pre><code class="javascript">// main.js
import * as fundebug from "fundebug-javascript";
import "./config"
import "./test"</code></pre>
<p>这种情况下,配置apikey的语句被import代替了,也就不存在所谓"import提升"的问题,Fundebug将可以正常报错。</p>
<p>最后,感谢Fundebug用户<strong>龙哥</strong>的反馈和协助!</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=qZBcoChXlMlHmlXPK%2BpcqQ%3D%3D.DlOOwMoWB3vF3KzNiRMG7rDknU8vagdfZxSUxDFuxdU%3D" rel="nofollow">《ECMAScript 6 入门》</a></li>
<li><a href="https://link.segmentfault.com/?enc=7CtD3%2BEDP%2B9lMZNtOHv5CQ%3D%3D.GFC%2FKvlUsqET2mQjeQL5cI1fps4JGzV3IxAbZRrcjXm9Ymk%2Feido7cInKODo1Hun" rel="nofollow">Fundebug文档 - JavaScript错误监控插件</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=B0EGo%2BAhjrs9NXcXi%2BHfCQ%3D%3D.uUtQ0bR1iPG8ucfEz84KKOjDUGv8xgAgG%2FNySpjHnWc%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=8nvj8IV6nSQCcKTU12Ps6g%3D%3D.NakFagmswGqNHFDgiL7q7jvSE9%2FCfWfiio71FpDZdGpajOgx%2FsiwgoahL0bHTS3e" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=5Jm0JCd1qv5E6fqsvqZTWA%3D%3D.Ix26d5p40077966xZD3MJ1%2Fyhn%2BZqzKVK5bpazA9X9w%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=k14WxgsaTUFneVYrHfZpGA%3D%3D.FXmG3WiEgXz6RdseI6xyyfEIq0R36qBLiYR6RAb6cp3V6PyzZ8uNSgmdh9LSb50pSFXTVhsDfd7JO9qK9NOMsYYqlZpBKQgUxQac2dReYsc%3D" rel="nofollow">https://blog.fundebug.com/2019/02/26/import-cause-fundebug-apikey-error/</a></p>
Fundebug后端Java异常监控插件更新至0.3.1,修复Maven下载失败的问题
https://segmentfault.com/a/1190000018318052
2019-02-27T10:33:33+08:00
2019-02-27T10:33:33+08:00
Fundebug
https://segmentfault.com/u/fundebug
2
<p><strong>摘要:</strong> <strong>0.3.1</strong>修复Maven下载失败的问题。</p>
<p><img src="/img/remote/1460000018318055?w=900&h=383" alt="" title=""></p>
<h3>监控Java应用</h3>
<h3>1. pom.xml 配置<a href="https://link.segmentfault.com/?enc=j9t6brxI9vFl%2BftrwY1v4A%3D%3D.0txDPP75CvasvJKrLlt1mnVjL0%2FhRzsQnjyShQgH9GaNgvVEOLmaciuVS%2Bu6xAtFEAg1TsaCxmwSd5zdLbscgA%3D%3D" rel="nofollow">fundebug-java</a>依赖</h3>
<pre><code class="xml"><dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-java</artifactId>
<version>0.3.1</version>
</dependency></code></pre>
<h3>2. 在项目中引入 fundebug 并配置 apikey</h3>
<pre><code class="java">import com.fundebug.Fundebug;
Fundebug fundebug = new Fundebug("apikey");</code></pre>
<p>注意:获取<strong>apikey</strong>需要<a href="https://link.segmentfault.com/?enc=huhdTZy6bd5bQA9S3E1Yew%3D%3D.JBFL5y3cVXDOKKk5Edxet0Hzdy7vdPW0VBtPRt%2BmNlnmicYEeZdP2dlJtijE1uaK" rel="nofollow">免费注册</a>帐号并且<a href="https://link.segmentfault.com/?enc=K1HDbzTguhIurJcS%2FiHtiQ%3D%3D.2KU%2Fuqxj8BeOTAtqFpW0Ii3odEIXWtlKA5rWgFPqL9ZCzG1jlV1f9y7c7n80aF%2BN" rel="nofollow">创建项目</a>。</p>
<p>可以参考 Demo 项目<a href="https://link.segmentfault.com/?enc=itJR5tjrCxM5CO6KccGKrw%3D%3D.D8nr23DBVEyGpWWGO3RgtYMSeZN3i3aXs0JLCq8FPew2qJi2egqrMu0InuQ%2FTg6m" rel="nofollow">Fundebug/fundebug-java-demo</a>。</p>
<h3>监控Spring应用</h3>
<h4>1. pom.xml配置<a href="https://link.segmentfault.com/?enc=2FhUvAOziQiMjdOpUIB0IQ%3D%3D.BuyBG2cqYfSKDvD2HYK0Btxl%2FHZdJ%2B2mX1NJh5breDgOQrSKizxh%2B%2BSWKjSJmV4%2B1NRHEMuecCFfSPiIwyHbEA%3D%3D" rel="nofollow">fundebug-spring</a>依赖</h4>
<pre><code class="xml"><dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-spring</artifactId>
<version>0.3.1</version>
</dependency></code></pre>
<h4>2. 在项目中引入fundebug并配置apikey</h4>
<p>新增FundebugConfig.java</p>
<pre><code class="java">import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.fundebug.Fundebug;
import com.fundebug.SpringConfig;
@Configuration
@Import(SpringConfig.class)
public class FundebugConfig {
@Bean
public Fundebug getBean() {
return new Fundebug("apikey");
}
}</code></pre>
<p>注意:获取<strong>apikey</strong>需要<a href="https://link.segmentfault.com/?enc=SDSUNqhaglpmvgQo%2BzaLTw%3D%3D.iSaZnyoH5wjPsaD9b0H%2Bar5kM7agh4jIGeAKhKZXe1vUz%2F3igOVWOuy2I%2BSoaPXi" rel="nofollow">免费注册</a>帐号并且<a href="https://link.segmentfault.com/?enc=k37SoSrmNNoxf%2Fi8RuOv%2BA%3D%3D.WeFo4w%2BUVUN%2BXqm3KAgWM%2Brkiu%2F6yIyMsWEItSLWLb9SQqnatWRA0GT9LEKfdd4O" rel="nofollow">创建项目</a>。</p>
<p>可以参考Demo项目<a href="https://link.segmentfault.com/?enc=U%2FJOlYpyI8fOto19fiKr0g%3D%3D.Aey8Y4%2BJP8JJIGDPqlvrYg1pUqQ%2B0n7sjdZKSfq%2F%2FAunsIkOIQo5ju6X9t2SalkHDMNicJCCsjtIo6xL5m2KJQ%3D%3D" rel="nofollow">Fundebug/fundebug-spring-demo</a>。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=48K8i8bV37iPBwvFqghY8g%3D%3D.9sniFnJOOFGmHrC1woaPg1sfO%2F8POFDwmQm3LUEu9CbfmqSE%2B2PqOVSifMjhVZS2" rel="nofollow">Fundebug文档 - Java</a></li>
<li><a href="https://link.segmentfault.com/?enc=vzi0J0L3ATs1hNnY2aDgDA%3D%3D.4TlB7%2B9XPTVdiQv61JAGsYuxpu8XqX3d9Uythy%2Fg46wBu6Rb9WUUJP27LNnHDy1foX%2BIBeqPlqiCvls3jTZ0ug%3D%3D" rel="nofollow">Maven入门教程</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=8loEm8NoNeuU2yL6gvZndg%3D%3D.VeLx57mUhN1RMglh0poLKHOgvc%2BgaLNSU%2FCLq0yxL%2Fw%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=rzmDrn769r0PPSC9USNDUg%3D%3D.1n7tj%2FcfM5JBI%2F1UuxIZsljLFQcH6UGDpqcf6GoHVN5z%2BbLENwnE7L2e66BexyNy" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=V180H9Of1%2F5hGhxyL9RmRw%3D%3D.4TDuD6fq0UDEZxDAv10jPBFQjYjNMc3Yo98UPN%2FD3uY%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=d2GhLp9dQMx0DShUHpUkgQ%3D%3D.M9jNh3yhOal6lRGmTpoDFB55r%2BmwjNBvkkoTdos2DuHY3U9Zc%2Bb1VraTfC%2B41VCjpN5%2B17FfSPyNREVohGVUHA%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/01/07/fundebug-java-0-2-0/</a></p>
Fundebug前端JavaScript插件更新至1.6.0,新增test()方法用于测试
https://segmentfault.com/a/1190000018302491
2019-02-26T09:33:49+08:00
2019-02-26T09:33:49+08:00
Fundebug
https://segmentfault.com/u/fundebug
6
<p><strong>摘要:</strong> 1.6.0新增fundebug.test()方法用于测试,请大家及时更新。</p>
<p><img src="/img/remote/1460000018302494?w=800&h=450" alt="" title=""></p>
<p>默认情况下,Fundebug 插件能够自动捕获未处理的错误(uncaught error)。另外,开发者也可以通过使用 Fundebug 提供的 API 发送其他错误信息:</p>
<ul>
<li><a href="https://link.segmentfault.com/?enc=f%2FlnG1iym%2BXoLf8Lb2GzPw%3D%3D.oMpj4e%2BMXbAY8KYNxwwtfM21JTiep9rmtoeXCMDcboTH90u82l2MYEUe%2FlhSU9XMOXGsI62h%2FIKH0TuidqgEVw%3D%3D" rel="nofollow">fundebug.test()</a></li>
<li><a href="https://link.segmentfault.com/?enc=pZAd9N0EgHOrkAgb2tfG7Q%3D%3D.IYhQVGcfObLBlq89rk%2FxyTxHe9vLkNdIDlmsCUVExbcPyit8%2B0zDWwEJPxkFW8g29Hyc%2FTD2V2LPkQRHmhdaMQ%3D%3D" rel="nofollow">fundebug.notify()</a></li>
<li><a href="https://link.segmentfault.com/?enc=Ilh62VdNSEUwUxpCHKKuXA%3D%3D.ot1mKpm%2BAIgTHI7SuvEKxQJRL56%2BzulBJr8TcHAqfe988%2Bqj5IywoAHDV9Ezuz5tc%2FqMJ5xfRuhUuxwRlcnil7BdxvEN9NnsG%2BzcsQdOCro%3D" rel="nofollow">fundebug.notifyError()</a></li>
</ul>
<h3>fundebug.test(name, message)</h3>
<p>使用 test() 方法,可以将测试数据发送到 Fundebug</p>
<p><strong>name</strong>: 测试名称,参数类型为字符串,默认值为"Test"</p>
<p><strong>message</strong>: 测试信息,参数类型为字符串, 默认值为"Hello, Fundebug!"</p>
<p>示例:</p>
<ul><li>不设置 name 与 message</li></ul>
<pre><code class="js">if ("fundebug" in window) {
fundebug.test();
}</code></pre>
<ul><li>设置 name 与 message</li></ul>
<pre><code class="js">if ("fundebug" in window) {
fundebug.test("Test", "Hello, Fundebug!");
}</code></pre>
<h3>报警规则</h3>
<p>test()方法用于测试,它发送的数据每次都会发送报警,每天报警次数限额为 20 次。</p>
<p>为了避免重复报警,请使用<a>notifyError()</a>或者<a>notify()</a>记录错误,按照默认的报警规则,同一个错误将只会在错误数达到阈值(10, 100, 100...)的时候报警。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=MhMEykoLJrbwFN9vlUkPqA%3D%3D.EjRzf2ZGMnfH58bERoONEyq7wdMcqbdmdBROgzaLn8eOJ28eNrUXiMkXhrRclM5zpjgZA7dahv%2BG21cP1w9E3g%3D%3D" rel="nofollow">Fundebug文档 - JavaScript插件版本</a></li>
<li><a href="https://link.segmentfault.com/?enc=FqtPVpKeBZoafjOKQ5oZIg%3D%3D.RQkuPZGsE4JogpAQyA8KbNoBjbeh%2BOJ9fRfJGEJBjPVLoGX2NYkSJDDupOp4KPvGJWCR0cHAX08rtBp3CAQU8g%3D%3D" rel="nofollow">Fundebug文档 - fundebug.test()</a></li>
<li><a href="https://link.segmentfault.com/?enc=hXiAYJdyiwbJVjLxx324zA%3D%3D.kHVADJacq7WyFTjYcACnTB%2BldAEqyQhAeP3beu%2FZmPaH9sDpjuDU6uEucwt93MHuyiXSQ88Vb5uDLxq%2FzvIunP3%2B2sLTwd0Jnlu7qS23kns%3D" rel="nofollow">黑科技!Fundebug支持可视化重现出错场景</a></li>
<li><a href="https://link.segmentfault.com/?enc=K04P0Z17cyFcMNdYAX%2FQDQ%3D%3D.yWXp14keS3OKU0sNelxwZj6Z9JCEDOpv05OgOw9OLfKAa9MnJ6YPdOZ3aLQEcBfECau8ddF6Xt3SXoO3q1%2BFRQ%3D%3D" rel="nofollow">Fundebug发布Vue插件,简化BUG监控接入代码</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=rJucdqCntl9H9wz2jRM%2Flw%3D%3D.pTr4cg%2FSSwSRiV6MF%2BFk2L8xikL0PL%2FKg8pEPSJqSYM%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=UEguH95piiNrAQ7aCzsVDQ%3D%3D.j8HdH99yOkNRl3w0dYZZunHOeFNt3V2zDy3Y%2BlIanLnodoW6pSqHKUVR5VC%2BDHWX" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=CwtTSr6G7L11M50ldRQtKg%3D%3D.TBQ2b1nc8O99I%2B0VVkwtKDk0K4obaSvcaxg2Dk5ENC0%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=7k9Hmqa8uJaVOW96YoeEmg%3D%3D.MX8mCojqlGrZIYjFmMsaBWFP%2BpkD51pY9P8wPOjpa9zZjbJzk5u2RNXZSTuhJdQq%2BHdLivWNTqY6V4rqLBCZ0A%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/02/25/fundebug-javascript-1-6-0/</a></p>
Java到底是编译型语言还是解释型语言?
https://segmentfault.com/a/1190000018005411
2019-01-24T11:03:37+08:00
2019-01-24T11:03:37+08:00
Fundebug
https://segmentfault.com/u/fundebug
8
<p><strong>转载自网络</strong></p>
<p>Java这个语言很神奇:</p>
<ul>
<li>你可以说它是编译型的。因为所有的Java代码都是要编译的,.java不经过编译就什么用都没有。</li>
<li>你可以说它是解释型的。因为java代码编译后不能直接运行,它是解释运行在JVM上的,所以它是解释运行的,那也就算是解释的了。</li>
<li>但是,现在的JVM为了效率,都有一些JIT优化。它又会把.class的二进制代码编译为本地的代码直接运行,所以,又是编译的。</li>
</ul>
<p>像C、C++ 他们经过一次编译之后直接可以编译成操作系统了解的类型,可以直接执行的 所以他们是编译型的语言。没有经过第二次的处理 而Java不一样他首先由编译器编译成.class类型的文件,这个是java自己类型的文件 然后在通过虚拟机(JVM)从.class文件中读一行解释执行一行,所以他是解释型的语言,而由于java对于多种不同的操作系统有不同的JVM所以 Java实现了真正意义上的跨平台! </p>
<p>请观看下面两张图 了解一下Java的虚拟机机制:</p>
<p><strong>Java的编译-->解释-->执行过程</strong></p>
<p><img src="/img/remote/1460000018005414" alt="" title=""></p>
<p><strong>Java的虚拟机</strong> </p>
<p><img src="/img/remote/1460000018005415?w=643&h=220" alt="" title=""></p>
<p>今天听到同事在讨论java是哪种类型的语言(编译型、解释型),以前稍微有些接触,但是概念比较模糊,为了不至于让别人的思想左右自己,所以查了些资料,找到了很多热心网友给出的答案,终于有些明白。这里先给出编译型语言和解释型语言的定义和区别。</p>
<ul>
<li>编译型语言:把做好的源程序全部编译成二进制代码的可运行程序。然后,可直接运行这个程序。</li>
<li>解释型语言:把做好的源程序翻译一句,然后执行一句,直至结束!</li>
<li>编译型语言,执行速度快、效率高;依靠编译器、跨平台性差些。</li>
<li>解释型语言,执行速度慢、效率低;依靠解释器、跨平台性好。</li>
</ul>
<p>个人认为,java是解释型的语言,因为虽然java也需要编译,编译成.class文件,但是并不是机器可以识别的语言,而是字节码,最终还是需要 jvm的解释,才能在各个平台执行,这同时也是java跨平台的原因。所以可是说java即是编译型的,也是解释型,但是假如非要归类的话,从概念上的定义,恐怕java应该归到解释型的语言中。</p>
<ul>
<li>编译型的语言包括:C、C++、Delphi、Pascal、Fortran</li>
<li>解释型的语言包括:Java、Basic、javascript</li>
</ul>
如何保证MongoDB的安全性?
https://segmentfault.com/a/1190000017961007
2019-01-21T08:46:09+08:00
2019-01-21T08:46:09+08:00
Fundebug
https://segmentfault.com/u/fundebug
5
<p>上周写了个简短的新闻<a href="https://link.segmentfault.com/?enc=TY%2F2CMZt6VPvte82Gh2Z%2FQ%3D%3D.zK6G3IiOWfERjN9VyAt0gB0fp%2FcnQji6yx8dm4iCMe%2ByIbHvQPnny2oRTMyHRbcNZ4gxSJt2ZREzPfOmNG0%2FqC6jiP0rN122CLMNhNzM2%2BM92w2CkQ%2BRkDnBrREkmVqO8oXYcU%2BQhYYw4HEXv4tE%2Bw%3D%3D" rel="nofollow">《MongoDB裸奔,2亿国人求职简历泄漏!》</a>:</p>
<blockquote>根据安全站点HackenProof的<a href="https://link.segmentfault.com/?enc=HJfxNjA45GD2TGZqYg3XtA%3D%3D.8EjILe5BW5pYXZBjZNA9uiR5btlKWF%2FP9t092YIKudTAolNkO4wmGVojzjQZe0ecaNUdCnbEG5P6dcGoyGNnWv9H7pd5ajLq%2BoA93%2FshiZM%3D" rel="nofollow">报告</a>,由于MongoDB数据库没有采取任何安全保护措施,导致共计202,730,434份国人求职简历泄漏。</blockquote>
<p>然后很多人<a href="https://link.segmentfault.com/?enc=5usFK47EhO0i%2FSVZrr90yg%3D%3D.94%2BnofD7wh6Aa268tlpd1%2FDzaRamNvsOIH14kGD%2FllHMPWBvO55vVxynIhZfZUJ9B3dfJcl%2F8BJhZomhpHHnRjlS481zaZsoqKJQEJsLKrk%3D" rel="nofollow">评论</a>说MongoDB躺枪了。</p>
<p>MongoDB确实躺枪了,因为<strong>这事的责任当然不在数据库,而在于使用数据库的人没有做必要的安全配置。</strong></p>
<p>那么我们应该如何保证MongoDB的安全性?下面我将介绍保护MongoDB的3个简单的方法:</p>
<ul>
<li>绑定局域网IP,杜绝互联网访问</li>
<li>配置防火墙,保护27017端口</li>
<li>配置账号密码,对数据库进行访问控制</li>
</ul>
<p>本教程所使用的系统配置如下:</p>
<ul>
<li>Ubuntu 16.04</li>
<li>mongodb 4.0.5</li>
</ul>
<p><strong>Ubuntu 16.04安装MongoDB</strong></p>
<p>参考MongoDB文档:<a href="https://link.segmentfault.com/?enc=FpL56WOkEQJposrl8dhaZQ%3D%3D.NcUsBHJAY%2BCfa1jeZJ6RphIbKQ7oEJOUPCZKJ6v2zFkEbgrqDST9MGqIqUCfu38qOhxxDcojF6dtFvD5GKxp%2BY5MoMP9Tl%2BxwpjWvq3svOY%3D" rel="nofollow">Install MongoDB Community Edition on Ubuntu</a></p>
<pre><code class="bash">sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org=4.0.5 mongodb-org-server=4.0.5 mongodb-org-shell=4.0.5 mongodb-org-mongos=4.0.5 mongodb-org-tools=4.0.5
sudo service mongod start</code></pre>
<h3>1. 绑定局域网IP,杜绝互联网访问</h3>
<p>话说MongoDB被黑了这么多年,自身确实有一定的责任。版本3.6之前,MongoDB默认绑定的居然是<strong>0.0.0.0</strong>,这就意味着我们可以通过互联网访问MongoDB,那黑客当然也可以。这样的默认配置是一个很大的安全漏洞,很多MongoDB初学者都栽在这一点。关于这个问题,MongoDB的<a href="https://link.segmentfault.com/?enc=VQz6dZChAc%2BUfRwyzwE%2Fig%3D%3D.7Qfg1PlGvXNpK2xJ5EiqozG76STpBI6CGTXmmCjzAszzEsFlHh9LWPZo9O%2BiJvjAvm6B7QKvyibQ4aHhHc1MmsVIF5lcac68K2jYiaDu9qA%3D" rel="nofollow">文档</a>说得很委婉:</p>
<blockquote>Default Bind to Localhost<p>Starting with MongoDB 3.6, MongoDB binaries, mongod and mongos, bind to localhost by default. From MongoDB versions 2.6 to 3.4, only the binaries from the official MongoDB RPM (Red Hat, CentOS, Fedora Linux, and derivatives) and DEB (Debian, Ubuntu, and derivatives) packages would bind to localhost by default.</p>
</blockquote>
<p>也就是说,从3.6开始,MongoDB默认绑定localhost,这就意味着我们只能在本机访问MongoDB。至于2.6到3.4,只有从MongoDB RPM与DEB下载的安装包才默认绑定localhost,换句话说,其他方式下载的安装包则默认绑定0.0.0.0。因此,如果你使用的MongoDB是3.6之前的版本,就要特别注意这一点了。</p>
<p>在开发环境下,MongoDB绑定localhost没毛病。但是,在生产环境下,我们通常会有多个节点,这时需要修改MongoDB绑定的IP,通过配置<a href="https://link.segmentfault.com/?enc=YJBrE%2Fag6nWld8FnDO08zw%3D%3D.9T3BcS4KlHYJu3dJ%2BENFmSEsps1l%2FYKv6O0p9eEfy6vpMg9pHf%2B2I0eyuMKQVqDRBvsv31APZncBGJP6dbZUoiVi38D8RHhJHxslmdLkmjQ%3D" rel="nofollow">net.bindIp</a>可以实现。</p>
<p>如果为了省事,直接把<a href="https://link.segmentfault.com/?enc=WtHFRZVpIo2h%2FkWfefHdxQ%3D%3D.61LIhw4sMTe%2Bd7F3YSmX0%2FxY5s86QzNmaPBLkaArNyJqB9tY8X3%2FdeyYEnkrqhDDtvO49CNrqDeGIdRsYeZxL8%2BMw%2BEOeKZDj17XzkMapSc%3D" rel="nofollow">net.bindIp</a>配置为0.0.0.0,那就不太妙了。正确的做法应该是绑定局域网IP,这样只有局域网内的节点可以访问MongoDB。除非黑客端掉了你的服务器,否则他是没法访问你的MongoDB的。</p>
<p>哪些IP是局域网的呢?按照标准,有下面这些网段:</p>
<ul>
<li>10.0.0.0 – 10.255.255.255</li>
<li>172.16.0.0 – 172.31.255.255</li>
<li>192.168.0.0 – 192.168.255.255</li>
</ul>
<p>最常用的局域网网段就是192.168.0.0到192.168.255.255了。</p>
<p><strong>修改MongoDB的配置文件</strong></p>
<pre><code class="bash">vim /etc/mongod.conf</code></pre>
<p>将<a href="https://link.segmentfault.com/?enc=fBEmPo7DOlPMw2UR%2FMTwGQ%3D%3D.zOs7Ab8uGmPIFxoDBOlKq3b5epsqUxuRVJGURw2zE6TiO%2BgQdYC5%2BdbP91ExXl830REDHapsSf2LT4%2FzGDvdSCMM6YlL20kZCOmtLVad2pw%3D" rel="nofollow">net.bindIp</a>设为局域网IP地址<strong>192.168.59.99</strong>:</p>
<pre><code>net:
port: 27017
bindIp: 192.168.59.99</code></pre>
<p><strong>重启MongoDB</strong></p>
<pre><code class="bash">sudo service mongod restart</code></pre>
<h3>2. 配置防火墙,保护27017端口</h3>
<p>MongoDB默认使用的是27017端口,我们应该配置本地防火墙把这个端口保护起来,禁止外部IP访问。</p>
<p>在MongoDB绑定0.0.0.0,且没有配置防火墙的情况下,使用nmap命令远程扫描27017端口,结果如下:</p>
<pre><code class="bash">nmap -p 27017 113.207.35.149
Starting Nmap 6.49BETA3 ( https://nmap.org ) at 2019-01-19 14:17 CST
Nmap scan report for 113.207.35.149
Host is up (0.042s latency).
PORT STATE SERVICE
27017/tcp open mongod
Nmap done: 1 IP address (1 host up) scanned in 14.34 seconds</code></pre>
<p>可知,27017端口是"open"的,这就意味着我们可以远程访问MongoDB数据库。</p>
<h4>配置UFW防火墙</h4>
<p>Ubuntu上默认的防火墙软件是<a href="https://link.segmentfault.com/?enc=HuwNrF%2FOFrhGGwgNxV4%2FOw%3D%3D.KOsez3je3xRIYlqFjRrUdNRU2o2SJOAQKpXfVzqnjHz%2BdiIzUpdu7XaaZghbKRFL" rel="nofollow">UFW</a>,配置起来非常简单。默认情况下,ufw并没有激活:</p>
<pre><code class="bash">sudo ufw status
Status: inactive</code></pre>
<p>执行以下命令,即可配置ufw规则,并启动防火墙:</p>
<pre><code class="bash">sudo ufw default deny incoming // 默认禁止访问本机所有端口
sudo ufw default allow outgoing // 允许本机访问外部网络
sudo ufw allow 22/tcp // 允许SSH登陆
sudo ufw allow from 192.168.59.100 to any port 27017 // 仅允许局域网内IP为192.168.59.100的服务器访问mongodb
sudo ufw enable</code></pre>
<p>我所配置的规则也非常容易理解,根据命令就能看出来。这时,再查看ufw的状态,可以发现防火墙已经激活了:</p>
<pre><code class="bash">sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
27017 ALLOW 192.168.59.100
22/tcp (v6) ALLOW Anywhere (v6)</code></pre>
<p>这时,再使用nmap命令远程扫描27017端口,结果如下:</p>
<pre><code class="bash">nmap -p 27017 113.207.35.149
Starting Nmap 6.49BETA3 ( https://nmap.org ) at 2019-01-19 14:40 CST
Nmap scan report for 113.207.35.149
Host is up (0.053s latency).
PORT STATE SERVICE
27017/tcp filtered mongod
Nmap done: 1 IP address (1 host up) scanned in 13.68 seconds</code></pre>
<p>可知,27017端口的状态为"filtered",已经被防火墙保护起来了,更加安全。</p>
<p>Linux上常用的防火墙工具还有iptables,这里就不再赘述了。</p>
<p>另外,云服务器都支持配置防火墙,也有必要配置一下,它们与本机的防火墙是独立的,可以共同来保证数据库的安全。</p>
<h3>3. 配置账号密码,对数据库进行访问控制</h3>
<p>默认情况下,MongoDB并没有配置账号和密码,黑客只要登陆你的服务器之后可以直接查看数据库。给MongoDB<a href="https://link.segmentfault.com/?enc=Og0lRAegn7EOwO4L%2BC%2BEXA%3D%3D.X8LA%2B2SQt4AsXIc1xTUZmL5nf1fyLtdUqjCbzrNcWV0zaB%2FuC1bQtGqU6x86my1X1ZTl3TiHOT26VEXOiThByA%3D%3D" rel="nofollow">配置账号密码</a>,可以有效解决这个问题。</p>
<p><strong>连接mongodb</strong></p>
<pre><code class="bash">mongo</code></pre>
<p><strong>配置账号密码</strong></p>
<p>账号为"myUserAdmin",密码为"abc123"。</p>
<pre><code class="bash">use admin
db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)</code></pre>
<p><strong>修改MongoDB的配置文件</strong></p>
<pre><code class="bash">vim /etc/mongod.conf</code></pre>
<p>将<a href="https://link.segmentfault.com/?enc=m%2Bhsl68P%2BZMFCObCBMedxA%3D%3D.igld%2BNkO2qROpP1VaiHz5u%2BGeHkOCrnybA3LOTVrBby4lgKWecRjuzbeOCgc%2BZatGsnmqbFLWUIxyCl60Ms%2BHu522uXCfRq2m5YgkRsjhyTg50rwvgNKP15PkEHw1ORv" rel="nofollow">security.authorization</a>设为"enabled":</p>
<pre><code>security:
authorization: enabled</code></pre>
<p><strong>重启MongoDB</strong></p>
<pre><code class="bash">sudo service mongod restart</code></pre>
<p><strong>连接mongodb</strong></p>
<p>再次连接mongodb时,则需要指定账号与密码。</p>
<pre><code class="txt">mongo -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"</code></pre>
<p>如果不提供账号密码,则无法查看数据库,会出现如下这种错误:</p>
<pre><code class="bash">show dbs
2019-01-20T22:13:53.477+0800 E QUERY [js] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "command listDatabases requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}</code></pre>
<p>另外,MongoDB还支持配置多个权限不同的账号,针对性地对特定数据库的读写权限进行配置。这样更加细致的访问控制可以增强安全性,举个不太恰当的例子,对于团队中的实习生,应该只给他们读权限,这样可以有效防止出现误操作导致删库等极端情况。</p>
<h3>总结</h3>
<p>可以发现,本文介绍的方法都非常简单,属于常识,但是都是必要的。作为数据库管理者,如果这些都没有配置,那显然是非常不专业的,责怪MongoDB也没有用,因为换个数据库也会有同样的问题。</p>
<p>根据MongoDB文档提供的<a href="https://link.segmentfault.com/?enc=J7ZqDGpjMCPnurbFbbviSw%3D%3D.9CD5a4yTQgy4fh8Y9zcyFWc%2B60qMmZ3Hho2Y4b%2BdDooUc44zEIXlpuAoRNu84e70rNFm%2BXevNhbkEiBXaOrBQh6vzEgsP6UBYWUP59BZKFY%3D" rel="nofollow">Security Checklist</a>,我们还可以使用TLS/SSL来加密MongoDB连接,这样做会在一定程度上牺牲性能,大家可以根据需要来配置。</p>
<p>另外,保证数据库的访问安全非常重要,同时也需要保证数据的安全性,做好必要的数据备份。关于如何保护数据的安全性,可以参考我们的博客《<a href="https://link.segmentfault.com/?enc=Dqf5Nr92yOsokPpKOBOWvQ%3D%3D.VwqWVC%2FnXcn1KyOcZeDU%2FtBzbLRRMEcQOZU5o1cy6px3wlUHc8WIuf1aMQgVsAV%2BhrDH4cfYg3mU70nrhORmb0Vp5f5kMigFwzvw93vPB%2BY%3D" rel="nofollow">Fundebug是这样备份数据的</a>》。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=Tzi771Q6K7fwk2Lj61Juow%3D%3D.uSngcTkqxcSFqTq6ze3U987%2FqNGM9Sio5AvF%2FDlp%2FpQs%2BqBZF0ogX1aVLZVDFBFrIZ8pE7dHmpqxTbq7QFx5Ei1T5kSH8ali13lsLifk7XT3hc%2FF64QHoAYRFoNgHo%2FhPdvV5gCbMBhaRFDwY6LfXQ%3D%3D" rel="nofollow">MongoDB裸奔,2亿国人求职简历泄漏!</a></li>
<li><a href="https://link.segmentfault.com/?enc=tVxPuAw%2FGRUq52B%2F4srBMA%3D%3D.OcULcFQ5%2Bb7dE8jomKlaWCeHBendu4ugMUF0P2c6u6VEZ9jpPIyYj35vkpjSvNaMuNhQSoQE5JXWgJIFCbpLcBpiw%2FDpYXPaZLn45EtMXOs%3D" rel="nofollow">Fundebug是这样备份数据的</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=QlZ0UFMAp2U5PvgLIXZ74g%3D%3D.oRV%2BZwXV1nuNNM2gfxXWo4U25ROeFPGXX377owB%2FXyU%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=ShT1tuFOKUdb7LaRDAA0Dw%3D%3D.86P3pwurUozAp3Ps0EGwd47ABSxDglzjb7qcWW6seLNadI3fVctdxnF8rxrNd3ir" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=yKmIqqLlw%2BRWcIdE%2BCYjdw%3D%3D.LFTAn3z7E7M2LEdUPdHO2B4HrmGNgAd1X3HHUwWXiGI%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=USnGjFARPXccrojzU9o%2FCA%3D%3D.UL0BrUPKSqFll%2FyMiNW%2FvQEPaV%2BAgR1DyOwVpB9NLlhyiGreFCD8gcP9Bdqs%2B%2By84LN6vhOJVIF6b6ch9kQFpw%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/01/21/how-to-protect-mongodb/</a></p>
Fundebug发布Vue插件,简化BUG监控接入代码
https://segmentfault.com/a/1190000017924729
2019-01-17T11:38:48+08:00
2019-01-17T11:38:48+08:00
Fundebug
https://segmentfault.com/u/fundebug
11
<p><strong>摘要:</strong> 代码越短越好!</p>
<p>我们发布了<a href="https://link.segmentfault.com/?enc=of4IZ%2FRuJtET2cfl3WkFmg%3D%3D.vUcYy6CQ0lSlcTMIyirwfF%2Fxyo86F5vYGvCzN7Q8ggOeeNYZrQxImLqnrsnxWSfr" rel="nofollow">fundebug-vue</a>插件,可以简化Vue框架接入<a href="https://link.segmentfault.com/?enc=9uFyKFFVnS3YOmhUgAV3Pw%3D%3D.hjfjymbj0t2xqzmr908F4E0iQ4ToIlF8Q6%2FGHZlQDbY%3D" rel="nofollow">Fundebug</a>的代码。</p>
<h3>Vue如何接入Fundebug</h3>
<p><strong>1. 安装<a href="https://link.segmentfault.com/?enc=GjfXalCdImC%2Bgi%2FCrlc3Zw%3D%3D.t47vxQoSru%2FyZBSDdGWhPzlgeBsF0oKdkOdiUEBVHdPjjmxyoCE%2FrZpOTYwedNHmJJ71h06MdInXONsAy8kDyA%3D%3D" rel="nofollow">fundebug-javascript</a>与<a href="https://link.segmentfault.com/?enc=xSzXNgKQxWD1soRbCVDZfA%3D%3D.IpwBkQTLI%2BrqXcmciclOAIYchctrqF%2Fch0upyCaFLxo4XUVwT1VCLLTjf3oNFIrP" rel="nofollow">fundebug-vue</a></strong></p>
<pre><code class="bash">npm install fundebug-javascript fundebug-vue</code></pre>
<p><strong>2. 配置</strong></p>
<pre><code class="javascript">import * as fundebug from "fundebug-javascript";
import fundebugVue from "fundebug-vue";
fundebug.apikey = "YOUR-APIKEY";
fundebugVue(fundebug, Vue);</code></pre>
<p>其中,获取<strong>apikey</strong>需要<a href="https://link.segmentfault.com/?enc=i5yfgPpEbILpN52vcmNnwA%3D%3D.aWU%2FYpNIgi9MV8sgM4FJtfQbnhAcd0xVSY9FIMO%2FDmBKX2sGJjtcmHcwPKL9PIHs" rel="nofollow">免费注册</a>帐号并且<a href="https://link.segmentfault.com/?enc=KJA27OU2LwNeD5eZAJJjHg%3D%3D.ns2EtlZdRpnutsGdB9icxLtFtFn3x%2FwHbzeumulxTwhaQDfJSxzyCnMccC3COcnI" rel="nofollow">创建项目</a>。</p>
<h3>关于<a href="https://link.segmentfault.com/?enc=gjvr2T2myczRLSX8D6Az5w%3D%3D.RsSXJ2ZTBiEUAy2mLFhF2GAFQhY795xW9CzFuKWD6r%2FChZJ7qm7xPTWVW3o2OiME" rel="nofollow">fundebug-vue</a>
</h3>
<p><a href="https://link.segmentfault.com/?enc=npEYIhSQo34B6pJc%2FUSLiA%3D%3D.SSc5Re0ZD1JMA4wpJbwA05hm3if%2F95xEGNw6sG%2BaB%2BxJzEL7WTBQ8lqsOWnxeRaK" rel="nofollow">fundebug-vue</a>非常简单,只是配置了Vue的<a href="https://link.segmentfault.com/?enc=gZw1%2Bbm7dAHsEKRxc498JA%3D%3D.kx33%2BVm8DQ9Pi2HhptAZZusmWSfYqIdIe4ygqj7RY4L2FixOcWq1xYybxxnE%2FEga" rel="nofollow">errorHandler</a>,源码只有40行,但是它可以简化Vue框架接入<a href="https://link.segmentfault.com/?enc=DZ9zwhMkISPUpWcrrcKjOA%3D%3D.9ljvqChlfogbJ425fIsFqZ8rZqKzd9K5S%2F5NxL%2FgZXM%3D" rel="nofollow">Fundebug</a>的代码。相比于直接配置errorHandler,使用fundebug-vue可以<strong>节省38行代码</strong>!</p>
<p>另外,由于Fundebug需要支持各种前端框架,因此为每一个框架开发独立的插件便于维护,也可以减少fundebug-javascript插件的大小。后续,我们会继续发布其他前端框架比如React与Angular的对应插件。</p>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=UcE%2FAcT6sME3nZyUkpGyXg%3D%3D.NBT8tWFSmnFql48Ad2V8fGaZwGjLq0IIL24I57XQ1II6d7%2FHPuQ3vOHzBLBkKeVEcFrvH%2FEIRImH%2BAOngZy64pMqlGundKCDsoC6N7vPdEI%3D" rel="nofollow">Fundebug文档:监控Vue.js</a></li></ul>
如何将JAR包发布到Maven中央仓库?
https://segmentfault.com/a/1190000017877798
2019-01-14T08:52:19+08:00
2019-01-14T08:52:19+08:00
Fundebug
https://segmentfault.com/u/fundebug
13
<p>将jar包发布到Maven中央仓库(<a href="https://link.segmentfault.com/?enc=lMpatEoq2XtxhTyc2MWfbQ%3D%3D.x%2Fgsed1rmrodLy7TGDtx1znWmXkHt5t1A871mTluVNg%3D" rel="nofollow">Maven Central Repository</a>),这样所有的Java开发者都可以使用Maven直接导入依赖,例如<a href="https://link.segmentfault.com/?enc=3qP%2FDiXIT5CmvlmXAoGJ1A%3D%3D.Iz4%2Bfb20U4eUhGT5s4JEtnew9s3b1zoPh3ufVKVU466Yvhrltdy5OCIwzJZ2OwXWU9qYtd6wiKdGfh8wxICvNg%3D%3D" rel="nofollow">fundebug-java</a>:</p>
<pre><code class="xml"><!-- https://mvnrepository.com/artifact/com.fundebug/fundebug-java -->
<dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-java</artifactId>
<version>0.2.0</version>
</dependency></code></pre>
<p>但是,Maven中央仓库并不支持直接发布jar包。我们需要将jar包发布到一些指定的第三方Maven仓库,然后该仓库再将jar包同步到Maven中央仓库。</p>
<p>其中,最"简单"的方式是通过<a href="https://link.segmentfault.com/?enc=2RUu9AU%2FegKO%2Flim8y5cog%3D%3D.vh8CSb%2F3kTyEjPPXM2Jz6aYuog0RtGIOHrYIYUumq5403bJ6mY48p82fnJhDdOfyk2CUR%2BguCNveqF%2BRH6vVbg%3D%3D" rel="nofollow">Sonatype OSSRH</a>仓库来发布jar包。接下来,我会介绍如何将jar包发布到Sonatype OSSRH。</p>
<p>本教程所使用的系统配置如下:</p>
<ul>
<li>OS:macOS 10.14.2</li>
<li>JDK:1.8.0_192</li>
<li>Maven:3.5.4</li>
</ul>
<h3>1. 注册JIRA账号</h3>
<p>JIRA是一个项目管理服务,类似于国内的Teambition。Sonatype通过JIRA来管理OSSRH仓库。</p>
<p>注册地址:<a href="https://link.segmentfault.com/?enc=Do682BSaUz5Uji6k6vFWlw%3D%3D.bO7jZC0h6Xs6MjVd5XtJLYhRa57DKRurHFIdHVfhzaEhVo4aES7%2FAw6%2BUtdP7OTLLnahRlZGS8yA22MKxl1LsA%3D%3D" rel="nofollow">https://issues.sonatype.org/secure/Signup!default.jspa</a></p>
<p>需要填写Email, Full Name, Username以及password,其中<strong>Username与Password后面的步骤需要用到</strong>,请记下来。</p>
<h3>2. 创建issue</h3>
<p>通过在JIRA上创建issue来申请发布新的jar包,Sonatype的工作人员会进行审核,审核不算严格,一般按照要求填写不会有问题。</p>
<p>创建链接:<a href="https://link.segmentfault.com/?enc=b0EwsqzcG926XwiPt6xexw%3D%3D.YB7qnctbnV380y66ABuud8s3HabPBuYE1eCFW%2FjsuQiaWU%2FnpxwpiRb0CfDcYRMHxatvFfHAgbIsCuIzgonKH7vKwKVl90fIivpdyyqo8ug%3D" rel="nofollow">https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134</a></p>
<p><img src="/img/remote/1460000017877801?w=824&h=941" alt="" title=""></p>
<p>创建issue的时候需要填写下面这些信息:</p>
<ul>
<li>Summary</li>
<li>Description</li>
<li>Group Id</li>
<li>Project URL</li>
<li>SCM url</li>
</ul>
<p>大家可以参考我申请发布<a href="https://link.segmentfault.com/?enc=1RtomNEVtapXAGLTHN%2FKww%3D%3D.tIs4HX8NhJf6ZDQmwCucaNC0WHJqxhBzaoLGsf1BMpWICH39rW98LRD6MEoIjgAF%2BhN55TQ2j4yZJ3tU%2BjRXJQ%3D%3D" rel="nofollow">fundebug-java</a>与<a href="https://link.segmentfault.com/?enc=pKR%2Bli4dfXLrgGGk9ne0Og%3D%3D.bPYvHPEPY8d6kIArbn7gq1cnvn5sgFxMJoi6NZNM35tGAYtLkuPgfeyYbMp7283XZ0teISQ7gfs9810u0QP5Ug%3D%3D" rel="nofollow">fundebug-spring</a>时所填写的内容:<a href="https://link.segmentfault.com/?enc=Uvm0i5up4lW3GCvSIMeTeA%3D%3D.MV5zrcvdR38Zje3y%2BPHDFgr94axdzy1YcLXdWhqQD5LdwJhB9MERSUazqF0xlBr3" rel="nofollow">OSSRH-45238</a></p>
<p>由于时差,前一天创建issue,第二天早上才会有回应。当issue的status变为<strong>RESOLVED</strong>,我们就可以进行下一步操作了。</p>
<h3>3. 安装并配置GPG</h3>
<p>发布到Maven仓库中的所有文件都要使用GPG签名,以保障完整性。因此,我们需要在本地安装并配置GPG。</p>
<p><strong>安装GPG</strong></p>
<p>MacBook安装GPG非常简单,下载并安装<a href="https://link.segmentfault.com/?enc=HQhQYDuAAHM1Kppfpxp4Gw%3D%3D.y7VDf2%2FWynSvcyoqK9i%2FW6%2BuhzoPBfgQlJTisAtuoPE%3D" rel="nofollow">GPG Suite</a>即可。</p>
<p><strong>生成GPG密钥对</strong></p>
<pre><code class="bash">gpg --gen-key</code></pre>
<p>生成密钥时将需要输入name、email以及password。<strong>password在之后的步骤需要用到</strong>,请记下来。</p>
<p><strong>上传GPG公钥</strong></p>
<p>将公钥上传到公共的密钥服务器,这样其他人才可以通过公钥来验证jar包的完整性。</p>
<pre><code class="bash">gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys CAB4165C69B699D989D2A62BD74A11D3F9F41243</code></pre>
<p>其中<strong>CAB4165C69B699D989D2A62BD74A11D3F9F41243</strong>为密钥的ID,可以通过<strong>gpg --list-keys</strong>命令查看</p>
<pre><code class="bash">gpg --list-keys
/Users/kiwenlau/.gnupg/pubring.kbx
----------------------------------
pub dsa2048 2010-08-19 [SC] [expires: 2020-06-15]
85E38F69046B44C1EC9FB07B76D78F0500D026C4
uid [ unknown] GPGTools Team <team@gpgtools.org>
sub elg2048 2010-08-19 [E] [expires: 2020-06-15]
sub rsa4096 2014-04-08 [S] [expires: 2024-01-02]
pub rsa2048 2019-01-03 [SC] [expires: 2021-01-02]
CAB4165C69B699D989D2A62BD74A11D3F9F41243
uid [ultimate] kiwenlau <kiwenlau@gmail.com>
sub rsa2048 2019-01-03 [E] [expires: 2021-01-02]</code></pre>
<h3>4. 配置Maven的setting.xml</h3>
<p>[setting.xml]()为Maven的全局配置文件,在MacBook上的位置为<strong>/usr/local/Cellar/maven/3.5.4/libexec/conf/settings.xml</strong>,我们需要将<strong>第1步</strong>配置的Username和Password添加到<code><servers></servers></code>标签中,这样我们才能将jar包部署到Sonatype OSSRH仓库:</p>
<pre><code class="xml"><servers>
<server>
<id>ossrh</id>
<username>Fundebug</username>
<password>passsword</password>
</server>
</servers></code></pre>
<h3>5. 配置项目的pom.xml</h3>
<p><strong>pom.xml</strong>挺长的。根据Sonatype OSSRH的<a href="https://link.segmentfault.com/?enc=Fi9mYtwSt9axaGd18pZY0g%3D%3D.OvT0ax5D7QU1dGig39zvJyk9ZGStOdxBLkPtgnXnfjqXAiNDFKNWFsLrSoqqo1UaGhQcDa10jUDgSpYWMryXhg%3D%3D" rel="nofollow">要求</a>,以下信息都必须配置:</p>
<ul>
<li>Supply Javadoc and Sources</li>
<li>Sign Files with GPG/PGP</li>
<li>
<p>Sufficient Metadata</p>
<ul>
<li>Correct Coordinates</li>
<li>Project Name, Description and URL</li>
<li>License Information</li>
<li>Developer Information</li>
<li>SCM Information</li>
</ul>
</li>
</ul>
<p>配置时参考我的pom.xml,根据需要修改即可。</p>
<pre><code class="xml"><project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-java-notifier</artifactId>
<version>0.2.0</version>
<packaging>pom</packaging>
<name>fundebug-java-notifier</name>
<url>https://github.com/Fundebug/fundebug-java-notifier</url>
<description>Capture Java and Spring exceptions automatically</description>
<licenses>
<license>
<name>Server Side Public License</name>
<url>https://www.mongodb.com/licensing/server-side-public-license</url>
<distribution>repo</distribution>
<comments>A not business-friendly OSS license</comments>
</license>
</licenses>
<scm>
<url>https://github.com/Fundebug/fundebug-java-notifier</url>
<connection>https://github.com/Fundebug/fundebug-java-notifier.git</connection>
</scm>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<developers>
<developer>
<name>kiwenlau</name>
<id>kiwenlau</id>
<email>kiwenlau@gmail.com</email>
<roles>
<role>Developer</role>
</roles>
<timezone>+8</timezone>
</developer>
</developers>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</profile>
</profiles>
<modules>
<module>fundebug-java</module>
<module>fundebug-spring</module>
<module>examples/hello-world</module>
<module>examples/spring-rest-api</module>
</modules>
</project></code></pre>
<h3>6. 发布jar包</h3>
<p>执行<strong>mvn clean deploy</strong>处理,即可将jar包发布到Sonatype OSSRH仓库。</p>
<pre><code class="bash">mvn clean deploy -projects fundebug-java,fundebug-spring </code></pre>
<p>我们的项目<a href="https://link.segmentfault.com/?enc=7A%2F%2BuiSZIJ4zpRZlKOGJww%3D%3D.A2KHgpV4SjRj2B81XblhWzykm%2BQ8opeKK0LNckzmGlPjvO%2Fcz9kjZP%2FUmjIHPrMi85iVhLSGCnsgxP34PjEBUA%3D%3D" rel="nofollow">fundebug-java-notifier</a>含有多个模块,仅需部署fundebug-java与fundebug-spring,因此使用<strong>-projects</strong>选项来指定。</p>
<p>第一次执行<strong>mvn clean deploy</strong>命令时,需要输入GPG密钥的密码。</p>
<p><strong>mvn clean deploy</strong>命令执行成功的输出是这样的(部分日志):</p>
<pre><code class="bash">[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] fundebug-java 0.2.0 ................................ SUCCESS [ 22.183 s]
[INFO] fundebug-spring 0.2.0 .............................. SUCCESS [ 16.383 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 38.728 s
[INFO] Finished at: 2019-01-12T20:10:16+08:00
[INFO] ------------------------------------------------------------------------</code></pre>
<h3>7. close并release</h3>
<p><strong>mvn clean deploy</strong>命令执行成功,使用JIRA账号登陆:<a href="https://link.segmentfault.com/?enc=Q69kK4dddtXwcDdHivgkxw%3D%3D.SZpez6UtFO0A25uflkjmhGIOMjR8MaN7rSrHexPHYhix8%2Fun%2B%2F7iSur3K%2Bc72nFR" rel="nofollow">https://oss.sonatype.org/#stagingRepositories</a>,就可以看到你所发布的jar包了:</p>
<p><img src="/img/remote/1460000017877802" alt="" title=""></p>
<p>选中对于的repository之后,点击箭头所指的<strong>close</strong>,close时会检查发布的构件是否符合<a href="https://link.segmentfault.com/?enc=zTIQq%2BKqZlEQJE5VEP6rhw%3D%3D.KxyhSd9rzZqurjGL%2FNXZVsbgggJ9LhqZVo2K7UGkoSqjk55sHBU0zOGqVhx%2BnnjpRWYBex0dBp3obgS1YeDn1A%3D%3D" rel="nofollow">要求</a>。若符合要求,则close成功,成功之后点击箭头所指的<strong>release</strong>,即可正式将jar包发布到Sonatype OSSRH仓库。</p>
<p><strong>release</strong>成功大概2个小时之后,该构件就会同步到<a href="https://link.segmentfault.com/?enc=5HMd4Km5mov0mFRhjhUmuA%3D%3D.5idig2twwe%2FNrLbPBpnkqpC14QMvTj5urOpviW2G6RY%3D" rel="nofollow">Maven中央仓库</a>:</p>
<p><img src="/img/remote/1460000017877803" alt="" title=""></p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=CqlQVqCFpJjfp4H8Cfouvg%3D%3D.lzOBymvDL9841gjZXbLkuLVgxpGMG6oJlNviXL1nt2Rfs54BALl6V3AcsSzNC5%2FI34kQ92t18PRNXBgcybSWKH3jt8R7DfVLtBzKX1n5Iho%3D" rel="nofollow">Guide to uploading artifacts to the Central Repository</a></li>
<li><a href="https://link.segmentfault.com/?enc=huUhteNVK3vT9Zivh6LfPw%3D%3D.d155D5gcAfsG947G%2BAIYTdPecMbnEM3PsC82%2FxmgrY5yBiE6BtLC38K40CoNTOoR0P128sU%2BltUrV6Pe3KJPMg%3D%3D" rel="nofollow">OSSRH Guide</a></li>
<li><a href="https://link.segmentfault.com/?enc=wgxTWYwnokfCQUjZbmS%2BIg%3D%3D.S3QIRqcjJnC98wIBhJkN7SXohEjQLAYI23hcL8VTBotOGDU77g%2BW8%2B%2BckRZ2D57Zapq2A9DJd3fIQ0IR1EAVjA%3D%3D" rel="nofollow">Maven入门教程</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=uwnWiePxxW9HxJDq03rBrw%3D%3D.mhNF9JWrIIiCmvpnVV9rilq9U9lhuGBl1YbxuaDlmyc%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=Dw0QL6MDc2EeCHLfdRgm9g%3D%3D.JqN9R25jTQJXBBJC%2B89ppRSGmvS%2FiJi3zuCAa4eWuqo1ejoNgURql2yhsFAMTm9E" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=NF10Z5PJBMKRa69uiKGChg%3D%3D.KUDyRI8rBoSAEroKgKUbExBLU2Zfe3H6ZAI3BWkCXjU%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=stqXIeo8iSzA%2BFYDChWGnw%3D%3D.7NCNzWnhuG7q8L5KNoXxZP6QWJDJSHg7kgUmjXlco823cF8ru2iosVLpmZ2qzSMyl4FIYz5%2FpHKTYdKeJOCM%2Fq%2BPim34d33W400Kinh4JnmFAFcvpeneYt43fxjNo%2FVL" rel="nofollow">https://blog.fundebug.com/2019/01/14/how-to-deploy-jar-to-maven-central-repository/</a></p>
Fundebug后端Java异常监控插件更新至0.2.0,支持Spring及Maven
https://segmentfault.com/a/1190000017809875
2019-01-08T15:37:42+08:00
2019-01-08T15:37:42+08:00
Fundebug
https://segmentfault.com/u/fundebug
8
<p><strong>摘要:</strong> <strong>0.2.0</strong>支持监控Spring应用,并且支持使用Maven接入插件,请大家及时更新。</p>
<p><img src="/img/remote/1460000017809878?w=900&h=383" alt="" title=""></p>
<h3>支持监控Spring应用</h3>
<h4>1. pom.xml配置<a href="https://link.segmentfault.com/?enc=Rt68cXPkd%2FWli6GNQ2KinA%3D%3D.8GHyO1lhlXg43scmnnnfJQyL6bqteB6gBLh7rpd%2Ffm7y46iXzC5sE%2FapBSrPQzcJSZzOI8%2FxpFp0pAn%2FhFeXJg%3D%3D" rel="nofollow">fundebug-spring</a>依赖</h4>
<pre><code class="xml"><dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-spring</artifactId>
<version>0.2.0</version>
</dependency></code></pre>
<h4>2. 在项目中引入fundebug并配置apikey</h4>
<p>新增FundebugConfig.java</p>
<pre><code class="java">import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.fundebug.Fundebug;
import com.fundebug.SpringConfig;
@Configuration
@Import(SpringConfig.class)
public class FundebugConfig {
@Bean
public Fundebug getBean() {
return new Fundebug("apikey");
}
}</code></pre>
<p>注意:获取<strong>apikey</strong>需要<a href="https://link.segmentfault.com/?enc=Eip%2BRl2IS5UxnRxR2C4kVw%3D%3D.uCTao5hun8jpum9oivw8G0D78n1nQHIr%2FcriFYe2nMRWmw5vJ5es70GdeRCqgFmQ" rel="nofollow">免费注册</a>帐号并且<a href="https://link.segmentfault.com/?enc=tgo89PeLGBx9O9BBaLRILg%3D%3D.Y7fnGjgoSOoeRiL2jd2Ep%2FNU2KlKN6E4s4R%2BXAl38uDHQLmVyPQhCsqdsNF82uUp" rel="nofollow">创建项目</a>。</p>
<p>可以参考Demo项目<a href="https://link.segmentfault.com/?enc=HtyWwBHHvc7x0GsxCHMr%2BA%3D%3D.E0vZE%2Fu5%2BZsoKVKzoh24rdYDVx4oy0fN7fBnmdotJbolpd5Jxe%2Fm57oVtXyCFLxzPpdHjbV%2BcOB%2F7SW3UWzErg%3D%3D" rel="nofollow">Fundebug/fundebug-spring-demo</a>。</p>
<h3>支持使用Maven接入插件</h3>
<p>Fundebug的Java异常监控插件<a href="https://link.segmentfault.com/?enc=DEvY4zJdeDFsarGvoLeNOA%3D%3D.xHz2txgJbzd6iN%2FuesclS3oKwfrorqGOUg3BkHbALDoR2QiWOY8POacgvkY2%2BVRAHgWcz3vUUldbuy%2B07%2FzpmA%3D%3D" rel="nofollow">fundebug-java</a>与<a href="https://link.segmentfault.com/?enc=FXLwkdyzANTJkF1%2BgrepfQ%3D%3D.w6COUPHEDClS7pjE5elrOECdiTdkuoxWY%2FuJOvUsFHZSdWyggSyy5FC6Iq%2FaxehsdyOkrwGE9dZghSdZe6p7Uw%3D%3D" rel="nofollow">fundebug-spring</a>都发布到了Maven中央仓库,因此可以在pom.xml直接配置依赖。</p>
<h4>接入fundebug-java</h4>
<pre><code class="xml"><dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-java</artifactId>
<version>0.2.0</version>
</dependency></code></pre>
<h4>接入fundebug-spring</h4>
<pre><code class="xml"><dependency>
<groupId>com.fundebug</groupId>
<artifactId>fundebug-spring</artifactId>
<version>0.2.0</version>
</dependency></code></pre>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=GWa2cshsY9ctacmr01BXIw%3D%3D.tsg2vsWAr9bK2kffEQJsch350aNEGbIKAkcnd%2BGYGW9PJQhH6bCLSI5ReplX3x%2F7" rel="nofollow">Fundebug文档 - Java</a></li>
<li><a href="https://link.segmentfault.com/?enc=9XDYIKRtzXiwFjgONKGLgg%3D%3D.dgvrQD7TBXJRYKBChdk%2FH5A%2FUma7VAYO1%2FHBWzpxXRDaLlwg%2BwnYjaiI2%2FWM9uzeA381y1SetPVLl0UrPLgldw%3D%3D" rel="nofollow">Maven入门教程</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=s%2BSvjJZzHybPZw222y6a7w%3D%3D.iTR5VSqprRs%2BT1GaP7X%2B3JEqQl5YaH33P3r5nmyofJI%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=3NHJGs8WQVFQjQccstvIPA%3D%3D.4n6lxuBB%2BGGNAPeW%2FD8CMv7b03Xx00KFUqs%2B%2FXNqQRVSBzkKGyiGsRe3YDhre1dp" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=bpHQFpfxn%2BwyeXmDzcm2Bw%3D%3D.ZAsF%2B7Fvqdcn5GZ2X27n1U%2FJh14u5UD2aygYK7i%2FbLE%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=Hz7Y8rsvV%2BDMRK6wTc5uEg%3D%3D.qOJaSntXdNf5%2FWLGMi5nHsuRi4tMnvDL8EQivKwXib0dx1HnTMNn8Qn1mztUKJVc5M4MEze39yiC3fzHcKElOw%3D%3D" rel="nofollow">https://blog.fundebug.com/2019/01/07/fundebug-java-0-2-0/</a></p>
价值1000万的腾讯云硬盘固件"BUG"
https://segmentfault.com/a/1190000015910909
2018-08-07T09:28:10+08:00
2018-08-07T09:28:10+08:00
Fundebug
https://segmentfault.com/u/fundebug
5
<p><strong>摘要:</strong> 阿门,愿云端没有BUG!</p>
<p><img src="/img/bV2rJd?w=800&h=450" alt="图片描述" title="图片描述"></p>
<p>这次,我从纯技术角度分析腾讯云与前沿数控的磁盘数据丢失事件,不站队。</p>
<h3>硬盘门</h3>
<p>这里说的硬盘门不是10年前陈老师的那一次,而聊的是最近“腾讯云”用户“前沿数控”的磁盘数据丢失。</p>
<p>关于这次事件,腾讯云是这样说的:</p>
<blockquote>近日,腾讯云用户北京清博数控科技有限公司所属“前沿数控”平台一块操作系统云盘,因受所在物理硬盘固件版本bug导致的静默错误(写入数据和读取出来的不一致)影响,文件系统元数据损坏。</blockquote>
<p>腾讯云多少有点打官腔,而前沿数控的说法更加直白:</p>
<blockquote>在使用腾讯云服务器8个月后,我们放在云服务器上的数据全部丢失,腾讯云所谓的三备份数据也全部离奇丢失!</blockquote>
<p>套用一下《天下无贼》的经典台词:</p>
<blockquote>21世纪什么最重要?数据!</blockquote>
<p>一个产品的数据如果丢失或者破坏的话,所受的打击是毁灭性的,因为老用户的服务无法恢复...腾讯云提出了136469的赔偿方案,而前沿数控索赔1000万,双方没有达成一致,这个事件才得以曝光。也就是说,在前沿数控看来,腾讯云的这个所谓的“物理硬盘固件版本bug”,价值1000万!BUG原来这么值钱啊,看来大家还是少写点BUG吧...</p>
<p>我们Fundebug同为创业公司,也是腾讯云和阿里云等云计算公司的用户,并且从事BUG监控服务(此事也涉及到BUG),因此会持续关注这个事件。</p>
<h3>腾讯云真的是硬盘固件BUG吗?</h3>
<p>腾讯云关于硬盘固件BUG的说明是这样的:</p>
<blockquote>近日,腾讯云用户北京清博数控科技有限公司所属“前沿数控”平台一块操作系统云盘,因受所在物理硬盘固件版本bug导致的静默错误(写入数据和读取出来的不一致)影响,文件系统元数据损坏。<p>腾讯云监控到异常后,第一时间向用户告知故障状态,并立即组织文件系统专家并联合厂商技术专家尝试修复数据。遗憾的是,虽经多方努力,最终仍有部分数据完整性校验失败。经过分析,该硬盘静默错误是在极小概率下被触发。我们随即对固件版本有bug的硬盘全部进行下线处理,确保相关隐患全部排除。</p>
</blockquote>
<p>由于腾讯云没有公布“物理硬盘固件版本bug”的任何技术细节,对于这件事的真相我有所疑问:</p>
<ul>
<li>硬盘的什么固件有BUG?</li>
<li>硬盘固件的哪个版本有BUG?</li>
<li>所谓的极小概率触发是BUG什么意思?究竟什么情况下会出现这个BUG?</li>
<li>硬盘固件应该升级到哪个版本才能修复BUG?</li>
<li>如何升级该硬盘固件?对固件版本有bug的硬盘全部进行下线处理是如何做到的?这个似乎不可能不影响硬盘用户吧?</li>
<li>我们Fundebug的BUG监控插件使用了腾讯云的CDN进行分发,发现CDN服务并不稳定,北京、杭州和天津用户访问时都出现过加载失败的情况,是否与这个BUG有关?(此事我们有向腾讯云提交工单。)</li>
</ul>
<p>2017年,国外的代码托管站点<a href="https://link.segmentfault.com/?enc=l4gq1lv4L3%2Fx4giltELRfg%3D%3D.ze4j0WIHHB7rkWgKMzXsfEPctAeWTdw7jlXhgvLsB%2BU%3D" rel="nofollow">Gitlab</a>的数据库被误删,他们在Youtube和Twitter上直播了整个修复过程,并且写了两篇博客详细公开了所有技术细节。这样做非常透明和公开,可以赢得用户的信任。</p>
<p>每个公司都会出现各种各样BUG或者故障,腾讯云也不能例外。用户对于云计算平台的要求非常高,因为涉及到能否正常提供服务,因此,作为腾讯云的用户,我们呼吁腾讯云公布这次事件的所有技术细节,这是厘清事件的最佳方式,也是对用户负责的一种表现。</p>
<h3>前沿数控难道没有备份数据?</h3>
<p>不难推测,前沿数控完全没有备份数据,它们完全依赖于腾讯云的承若的"99.9999999%的数据可靠性,搭载了云硬盘提供三副本存储策略"。我不清楚腾讯云的这个99.9999999%的数据可靠性是怎么计算出来的,也不知道腾讯云的三副本存储策略是怎么回事,这一点需要腾讯云提供详细的说明。但是,对于每一个产品来说,备份数据,至少备份一下核心数据,这是最基本的常识。所以在这一点上,前沿数控显然存在失误。</p>
<p>所有的创业者和开发者都应该从这个事件吸取教训,不要偷懒,严格备份数据,否则数据一旦出问题,后果非常严重。这里简单介绍一下Fundebug是如何备份数据的,给大家提供参考,以后我会详细介绍我们的数据备份方案:</p>
<table>
<thead><tr>
<th>备份方案</th>
<th>时间粒度</th>
<th>细节</th>
</tr></thead>
<tbody>
<tr>
<td>MongoDB复制集</td>
<td>实时</td>
<td>搭建3个节点(1个Primary和2个Secondary)的MongoDB复制集,实时同步数据</td>
</tr>
<tr>
<td>阿里云服务器磁盘快照</td>
<td>每天</td>
<td>设置每天凌晨自动快照所有磁盘,包括系统盘和数据盘</td>
</tr>
<tr>
<td>mongodump导出核心数据</td>
<td>每天</td>
<td>每天凌晨将MongoDB核心数据导出到复制集之外的服务器磁盘(该磁盘会每天进行快照)</td>
</tr>
<tr>
<td>阿里云对象存储</td>
<td>每天</td>
<td>每天凌晨将mongodup导出的数据使用gpg非对称加密之后,上传到阿里云深圳数据中心的对象存储,设置阿里云自动同步到杭州数据中心,每份数据保留1个月</td>
</tr>
</tbody>
</table>
<p>对数据对多个粒度的备份,是非常必要的,无论你使用哪一家云计算平台,无论该平台给了你怎样的承若。如果依赖云计算平台,大概是靠不住的,而且他们的应急处理速度显然没有自己来的快,因为只有开发者自己最了解应用数据,知道如何备份如何恢复才能尽量降低损失。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=zPRJLbmuxR3Kk8DBA5xZ4g%3D%3D.npIqBBRxYjshDJubB1ASIw9m1MbyJ08HrsryOuAWRUXW1F27TibscyPi6ocVv0ET1geuRzuhkpeQh58HxtjnzA%3D%3D" rel="nofollow">腾讯云 - 关于用户“前沿数控”数据完整性受损及腾讯云补偿措施的说明</a></li>
<li><a href="https://link.segmentfault.com/?enc=2sVlNu%2FE209bTKO7KFe1IQ%3D%3D.LdGQ4rW%2Fh6QtaxVV9VkmsUzVUJ9VGdH7tpn7zqYmHEZlSfQnwBm5%2FTkl3S3u6fNk2tXsiQaNvPRvQRxKa%2BGsNA%3D%3D" rel="nofollow">前沿数控- 腾讯云给一家创业公司带来的灾难!</a></li>
<li><a href="https://link.segmentfault.com/?enc=ukmFNN1dpSYK%2BHDUXbW2jw%3D%3D.bGzUhqBGw7bIZ9hbCNyOFUZ%2BpLL2CuEGwv5eZuze7Ivh7MAaZFEXcMQFbC%2B34H8bDWXfXtt7HgMCongRKCikFw%3D%3D" rel="nofollow">前沿数控- 对腾讯云官方回应“前沿数控平台数据丢失”事件的严重不满及声明</a></li>
<li><a href="https://link.segmentfault.com/?enc=1mF%2BY0dPHGy7d7eXGta22Q%3D%3D.55u2YGXz35VuugP50RiWkOq%2BBPWS8L9YCD7RXtk2fUO98Kc9Ph68l%2BSzjTyUBjf4" rel="nofollow">陈皓 - 从GITLAB误删除数据库想到的</a></li>
<li><a href="https://link.segmentfault.com/?enc=GSqE%2FmwSC2vzaG4Vols6UQ%3D%3D.vMvJP5XY68xIVkjTNEjaDTy6vs6a2uBeVCeaxiTPZYwKqW8N%2BuUPuwRvVO7pIu%2F4AYE6pFYnJtTfQVp1b1iXxz6l5u1XW9eudgW7rN8f68g%3D" rel="nofollow">GitLab - GitLab.com database incident</a></li>
<li><a href="https://link.segmentfault.com/?enc=YR8aLFHYNEJ9%2FxMbldKphQ%3D%3D.UniL092z%2FeBLpkLvV9lXa3Ke0FkIbSfR2qgi7JmK7%2F2brBcWBKiIxHq9Dikpv7CudELfbXA7wL1JhN2LiNddEgKPU88aB1yL4EkkRK6XQj9165Cs%2BSp3m%2BoncNzlkBB5" rel="nofollow">GitLab - Postmortem of database outage of January 31</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=cfX6EqAziWIm69SzsSSdlA%3D%3D.9o7UqYXb%2B4%2F2s%2FVwMwh1%2FRkybwllILaih5B%2BGZea2MQ%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏,Node.js和Java实时BUG监控。<br>自从2016年双十一正式上线,Fundebug累计处理了5亿+错误事件,得到了众多知名用户的认可。欢迎免费试用!</p>
教你快速撸一个免费HTTPS证书
https://segmentfault.com/a/1190000015758393
2018-07-25T10:33:52+08:00
2018-07-25T10:33:52+08:00
Fundebug
https://segmentfault.com/u/fundebug
26
<p><strong>摘要:</strong> 最受欢迎的免费HTTPS证书,了解一下?</p>
<p><img src="/img/bVbdmOE?w=800&h=450" alt="图片描述" title="图片描述"><br>HTTPS已成为业界标准,这篇博客将教你申请<a href="https://link.segmentfault.com/?enc=jmMqwjKoAeC%2FupQbfetShg%3D%3D.%2BxeRVvX95NnDevANkOA1z9aSfszrQm9nZy11YxXpM9s%3D" rel="nofollow">Let's Encrypt</a>的免费HTTPS证书。</p>
<p>本文的操作是在Ubuntu 16.04下进行,使用nginx作为Web服务器。</p>
<h3>1. 安装Certbot</h3>
<p><a href="https://link.segmentfault.com/?enc=Jk%2BLbF4WyvgRYPLo%2FRVDuQ%3D%3D.qf3BSzk6kxONjWxiF7J%2BqqRYps9r42vHqYCCE8k7Gtw%3D" rel="nofollow">Certbot</a>可以用于管理(申请、更新、配置、撤销和删除等)Let's Encrypt证书。这里安装的是带nginx插件的certbot:</p>
<pre><code class="bash">sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:certbot/certbot
sudo apt-get update
sudo apt-get install -y python-certbot-nginx</code></pre>
<h3>2. 配置Nginx</h3>
<pre><code class="bash">vim /etc/nginx/conf.d/fundebug.conf</code></pre>
<p>此时还没有HTTPS证书,因此域名只能使用80端口而非443端口,网站只能通过http协议而非https协议访问:<a href="https://link.segmentfault.com/?enc=mYrKK8Rx9Mam8NCbaY7IPQ%3D%3D.qHddbKOQBlaL6sTNGtWXjLVgPM1S5jrODPj%2BJ0hLybM%3D" rel="nofollow">http://www.fundebug.com</a>。</p>
<pre><code class="nginx">server
{
listen 80;
server_name www.fundebug.com;
}</code></pre>
<p>重启nginx:</p>
<pre><code class="bash">systemctl restart nginx</code></pre>
<h3>3. 配置DNS</h3>
<p>使域名<a href="https://link.segmentfault.com/?enc=AETmHcB4EwxX%2BunwM%2Bh%2BCg%3D%3D.j0BGd1HYST2Lgb6rPqvDc4SJDOm6X%2B8A0ynuqLavhU8%3D" rel="nofollow">www.fundebug.com</a>指向nginx所在服务器的IP:</p>
<p><img src="/img/bVbdmOD?w=744&h=136" alt="图片描述" title="图片描述"></p>
<p><em>如果你想发现代码中隐藏的BUG,欢迎免费试用最专业的BUG实时监控平台<a href="https://link.segmentfault.com/?enc=DdQrQQ5WGfj3%2FmtegxEzCA%3D%3D.M1IPGtW02U2Vr%2FQeb7P2WlYXIJ5kD3NIC2oWGv1BjuI%3D" rel="nofollow">Fundebug</a>!</em></p>
<h3>4. 申请证书</h3>
<p>使用certbot命令为<a href="https://link.segmentfault.com/?enc=LY%2BVwnS1v6nTJYMCTdgozA%3D%3D.rbcuO72mEn0%2FloJ8hjSwAgTkl4nfxhmoJI7DGkZUuSw%3D" rel="nofollow">www.fundebug.com</a>申请HTTPS证书。<strong>--nginx</strong>选项表示Web服务器为nginx,<strong>-d</strong>选项指定域名,<strong>-n</strong>选项表示非交互式运行命令。若去除<strong>-n</strong>选项,则终端会提醒你选择是否将http请求重定向为https请求。</p>
<pre><code class="bash">certbot --nginx -d www.fundebug.com -n</code></pre>
<p>证书申请成功之后,会看到以下信息。Let's Encrypt证书的有效期只有3个月,但是<a href="https://link.segmentfault.com/?enc=j7U6F5DPaht56k8g4JmlpQ%3D%3D.yIrawjnAqOSqez0NpZtzaC2BwxmITTB1lZiP6gY04GVI5XrnWDOwegCIjSQzENloHPGVZhXPpxQ1otuBY9AkfI%2BjgtP7ItYoHMbHEKEN6X8%3D" rel="nofollow">Certbot会通过Cron和systemd timer自动更新证书</a>,证书的时效性不用担心。</p>
<pre><code>IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.fundebug.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.fundebug.com/privkey.pem
Your cert will expire on 2018-09-29. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le</code></pre>
<p>HTTPS证书相关的文件在<strong>/etc/letsencrypt/</strong>目录中:</p>
<pre><code class="bash">find /etc/letsencrypt/ -name "*www.fundebug.com*"
/etc/letsencrypt/renewal/www.fundebug.com.conf
/etc/letsencrypt/archive/www.fundebug.com
/etc/letsencrypt/live/www.fundebug.com</code></pre>
<p>certbot会自动修改nginx配置文件:</p>
<pre><code class="bash">cat /etc/nginx/conf.d/fundebug.conf</code></pre>
<p>nginx监听了443端口并配置了HTTPS证书,这时我们可以通过HTTPS协议访问了!<a href="https://link.segmentfault.com/?enc=UHN5ks%2B%2BBcmrJicgmSMzCg%3D%3D.3%2Buy%2BxYKq9OLbpj3ct6Ib%2BKpOx%2BxWPiXnPDMLi9E0rs%3D" rel="nofollow">https://www.fundebug.com</a></p>
<pre><code class="nginx">server
{
listen 80;
server_name www.fundebug.com;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.fundebug.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.fundebug.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}</code></pre>
<h3>参考</h3>
<ul><li><a href="https://link.segmentfault.com/?enc=a%2BQqr%2FJwCFo3OEFxvZtvqA%3D%3D.3eyOnt7pL2Yw%2BwzqdAXf2VQIdYhS1xKRXVtVewVBLctFuYJQ%2FHRxQRZf%2BfsltdnLIy8aphAOaTEz0JKr0L2Mvg%3D%3D" rel="nofollow">Certbot文档:Nginx on Ubuntu 16.04 (xenial)</a></li></ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=1nPnA0uHSTE0hgx%2FXRYzGA%3D%3D.F4h%2B4yXZqzrySSzv%2BLnENCcTJALqNToA4u9mJ4kW7Bw%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家<a href="https://link.segmentfault.com/?enc=bBk4%2FVFGInrUCbtdrYaOBw%3D%3D.qZrY5i53XSqjwhMrCrxQxzm%2Fj2qm3VBts0EVJplAGl56vO9NLAbCLicysxS8hO55" rel="nofollow">免费试用</a>!</p>
<p><img src="/img/remote/1460000016902244?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者Fundebug以及本文地址:<br><a href="https://link.segmentfault.com/?enc=kkVqC8xz1fHZNL%2Fk6XOGEw%3D%3D.QPkpF8MXkThw9kxcGtNGtDi5ieWYHbHdx7hQrb5vM%2B9TDIcdSUkCiWhPi8GY%2FGPptaExZQmOXUGjTmUYBcA5vCQyC8%2FN1tbYEj77k4cmGzw%3D" rel="nofollow">https://blog.fundebug.com/2018/07/06/apply-lets-encrypt-certificate/</a></p>
详解JavaScript之神奇的Object.defineProperty
https://segmentfault.com/a/1190000015703715
2018-07-20T10:25:02+08:00
2018-07-20T10:25:02+08:00
Fundebug
https://segmentfault.com/u/fundebug
28
<p><strong>摘要:</strong> JavaScript有个很神奇的<a href="https://link.segmentfault.com/?enc=FwPuSwR%2FzOdaefEiJGc0Lw%3D%3D.KEr5OhWm1iUgFe34qTeoxvLxgNqvpmYRVpZoUGN34yRneLjVxMK8X8YZuIPGYqJiooFM76KKe%2BlZ%2BdF7ov6pydcrg%2BsNXtOO8d%2B2k%2FdruNFSBStk05TbuKfUgXKlNBzqJ6M2CXBDnlExSroPN1VndA%3D%3D" rel="nofollow">Object.defineProperty()</a>,了解一下?</p>
<h3>=与Object.defineProperty</h3>
<p>为JavaScript对象新增或者修改属性,有两种不同方式:<strong>直接使用=赋值</strong>或者<strong>使用Object.defineProperty()定义</strong>。如下:</p>
<pre><code class="javascript">// 示例1
var obj = {};
// 直接使用=赋值
obj.a = 1;
// 使用Object.defineProperty定义
Object.defineProperty(obj, "b",
{
value: 2
});
console.log(obj) // 打印"{a: 1, b: 2}"</code></pre>
<p>这样看两者似乎没有区别,对吧?但是,如果使用<a href="https://link.segmentfault.com/?enc=eViyM8ehOT6Ws7Uvw5SjkQ%3D%3D.rGYdp%2BaWE1UOR1g8tmSlx2ERq7MaAnKqaI8BoGc1dZ%2FTTTdBpahfm8aAXkTexj9yMBEAEMRVS%2B4Yzcu5%2BINb%2F1mmKFLW4Pc%2BxwNa2m9bhCsWAmGkYvxbXSOlkhwJHWw5K3oo9sSIpOVxh%2BMGhaI2cGb0z0pPW6ev5bahvDFOFOo%3D" rel="nofollow">Object.getOwnPropertyDescriptor()</a>查看obj.a与obj.b的属性的<strong>描述描述符(property descriptor)</strong>时,会发现=与Object.defineProperty并不一样:</p>
<pre><code class="javascript">// 示例2
var obj = {};
obj.a = 1;
Object.defineProperty(obj, "b",
{
value: 2
});
console.log(Object.getOwnPropertyDescriptor(obj, "a")); // 打印"{value: 1, writable: true, enumerable: true, configurable: true}"
console.log(Object.getOwnPropertyDescriptor(obj, "b")); // 打印"{value: 2, writable: false, enumerable: false, configurable: false}"</code></pre>
<p>可知,使用=赋值时,属性的属性描述符value是可以修改的,而writable、enumerable和configurable都为true。</p>
<p>而使用Object.defineProperty()定义的属性的属性描述符writable、enumerable和configurable默认值为false,但是都可以修改。对于writable、enumerable和configurable的含义,从名字就不难猜中,后文也会详细介绍。</p>
<p>使用=赋值,等价于使用Object.defineProperty()定义时,同时将writable、enumerable和configurable设为true。代码示例3和4是等价的:</p>
<pre><code class="javascript">// 示例3
var obj = {};
obj.name = "Fundebug";
console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}</code></pre>
<pre><code class="javascript">// 示例4
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: true,
enumerable: true,
configurable: true
});
console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}</code></pre>
<h3>Object.defineProperty()</h3>
<p>使用Object.defineProperty()定义时若只定义value,则writable、enumerable和configurable默认值为false。代码示例5和6是等价的:</p>
<pre><code class="javascript">// 示例5
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug"
});
console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}</code></pre>
<pre><code class="javascript">// 示例6
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: false,
enumerable: false,
configurable: false
});
console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}</code></pre>
<p>由于writable、enumerable和configurable都是false,导致obj.name属性不能赋值、不能遍历而且不能删除:</p>
<pre><code class="javascript">// 示例7
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug"
});
// writable为false,无法赋值
obj.name = "云麒";
console.log(obj.name); // 打印"Fundebug"
// enumerable为false,无法遍历
console.log(Object.keys(obj)); // 打印"[]"
// configurable为false,无法删除
delete obj.name;
console.log(obj.name); // 打印"Fundebug"</code></pre>
<p>若在严格模式("use strict")下,示例7中的代码会报错,下文可见。</p>
<h3>writable</h3>
<p>writable为false时,属性不能再次赋值,严格模式下会报错<strong>“Cannot assign to read only property”</strong>(<em>如果你希望实时监控类似的应用错误的话,欢迎免费试用<a href="https://link.segmentfault.com/?enc=EHlt4vAgHXi4ZNR1MZZMmA%3D%3D.tYHmbqMIMVyOo%2FQiRTY3i9%2FBK2DqGeC9FHZ28VhQvM8%3D" rel="nofollow">Fundebug</a>,我们支持前端网页、微信小程序、微信小游戏,Node.js以及Java错误监控!</em>):</p>
<pre><code class="javascript">// 示例8
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: false,
enumerable: true,
configurable: true
});
obj.name = "云麒"; // 报错“Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>'”</code></pre>
<p>writable为true时,属性可以赋值,这一点读者不妨自行测试。</p>
<h3>enumerable</h3>
<p>enumerable为false时,属性不能遍历:</p>
<pre><code class="javascript">// 示例9
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: true,
enumerable: false,
configurable: true
});
console.log(Object.keys(obj)) // 打印"[]"</code></pre>
<p>enumerable为true时,属性可以遍历,这一点读者不妨自行测试。</p>
<h3>configurable</h3>
<p>enumerable为false时,属性不能删除,严格模式下会报错<strong>“Cannot delete property”</strong>:</p>
<pre><code class="javascript">// 示例10
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: true,
enumerable: true,
configurable: false
});
delete obj.name // 报错“Uncaught TypeError: Cannot delete property 'name' of #<Object>”</code></pre>
<p>enumerable为true时,属性可以删除,这一点读者不妨自行测试。</p>
<h3>writable与configurable</h3>
<p>当writable与enumerable同时为false时,属性不能重新使用Object.defineProperty()定义,严格模式下会报错<strong>“Cannot redefine property”</strong>:</p>
<pre><code class="javascript">// 示例11
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: false,
configurable: false
})
Object.defineProperty(obj, "name",
{
value: "云麒"
}) // 报错“Uncaught TypeError: Cannot redefine property: name”</code></pre>
<p>当writable或者enumerable为true时,属性可以重新使用Object.defineProperty()定义,这一点读者不妨自行测试。</p>
<p>本文所有代码示例都在Chrome 67上测试。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=6ZqLFf39v18zu%2B8gWQ0lzg%3D%3D.xCNQM2DmzksCt86zY3qNwAcKIgk%2FaFw%2FoNucFhLVEg9CFcaJeN0YcWWYgKMERLkwjis29pwMdyVtAlMU3xJ3i%2Biurs39fD4pTUqT%2FbKu3hoifqrj7nW8dcxAGiIc19nEPj1w3aDaJeH87B7wjySxbw%3D%3D" rel="nofollow">Object.defineProperty()</a></li>
<li><a href="https://link.segmentfault.com/?enc=EEA0FtZNUOk8LcOj1W%2FTiQ%3D%3D.uOuaQdbNIXKJklJ59QTv69CmTAApRJ%2Ba%2FGlTip1zvwO1o4VmTsdBeknXKo9HCBqyuXeoVQpK0pt%2BBg1b31XCXcmiVRc9e1iOGxPadQDOTqhD6GYCfaUPfWHUqkGc5HApohwkqrNnH%2FP9v7zvcItD3dEdrJJMdkQD8rY%2Frn4GpHE%3D" rel="nofollow">Object.getOwnPropertyDescriptor()</a></li>
<li><a href="https://link.segmentfault.com/?enc=KtCv6D2L%2B3fbl0AopBj2aQ%3D%3D.bI9094B7GBeLcJMD2Kd6UAEpIBLOdjMyrlnXy%2BfIqmuaAa2C1rRclSNUnKoX6BsVwF360BClVGHeaCjfF9oAhkcliQMXAuP0ERVQcm3bUEWKZ%2B4sE2NRckx%2BAAJkw%2BAzN1E47uQMy0eRz00LMRIKOIw9HlGJEUrjslV8Pma3pd0%3D" rel="nofollow">StackOverflow: Why can't I redefine a property in a Javascript object?</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=RvXvzX6vS6g53Et2XqBWhQ%3D%3D.IElj3Ua%2F3rk8JGoA47OR%2F9AdqxZ6Knf3jLfhrzGHXm8%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,得到了Google、360、金山软件等众多知名用户的认可。欢迎免费试用!</p>
<p><img src="/img/bVbhe1G?w=400&h=225" alt="图片描述" title="图片描述"></p>
<h3>版权声明</h3>
<p>转载时请注明作者Fundebug以及本文地址:<br><a href="https://link.segmentfault.com/?enc=9W3sIRA9XmWleytXaeqEMw%3D%3D.iwpHqpVwIL4nQhD%2F4Jd53u0lxUKhysyi082F%2BniOFjWuVBQs%2B3NR481Z3MrhPnbGj6N%2BcRVSQHfyO0ZvOlkcf6E6yJITBPo%2FAp%2BI5O6nwNI%3D" rel="nofollow">https://blog.fundebug.com/2018/07/05/javascript-object-defineproperty/</a></p>
webpack运行Babel教程
https://segmentfault.com/a/1190000015354311
2018-06-22T10:21:57+08:00
2018-06-22T10:21:57+08:00
Fundebug
https://segmentfault.com/u/fundebug
8
<p><strong>摘要:</strong> Babel是转码器,webpack是打包工具,它们应该如何一起使用呢?</p>
<ul><li>GitHub仓库:<a href="https://link.segmentfault.com/?enc=fInCDMh3H1bG7E6vt75FBQ%3D%3D.85TVqOABYOnYOxbxu08CZjByTac2MC%2FNn%2BfWXpdE%2Bl4Q5Ll24tNX9VWIFrgJAxRT%2BAhpIRsd0%2F%2BmkoGpSDif0V3ACETqFizFYpm7YJKVZXU%3D" rel="nofollow">Fundebug/webpack-babel-tutorial</a>
</li></ul>
<p><img src="/img/bVbce0i?w=800&h=450" alt="图片描述" title="图片描述"></p>
<h3>ES6 + IE10 = 语法错误!</h3>
<p><a href="https://link.segmentfault.com/?enc=vexYksa5iX3GTfynOM%2FPMw%3D%3D.Y9nWiOkntVijf%2FRJikDjhm0LzBuM7KiuuKsf3Q4BxuTjxJlsY%2FT25QtalV6FvWj5QYujJtB5d7rQHnjyOyIQrFrMetiVcvp6MGU5dcicEu8%3D" rel="nofollow">test.js</a>使用了ES6的<a href="https://link.segmentfault.com/?enc=Ve2gsB59XEH5C4CMFTcV%2BQ%3D%3D.Ce0RRNaRw7p4H9MLQrKrTgSf8rbMxnrxuaIIvdhmH%2By8YofI3v68o06%2Fzucjj4G3%2F5Gmkz8t%2F3BtNiyAsob78nCoHkYDTYUOXnnNcfIi0soolPcfRmi0Bfjs8qH72IKo" rel="nofollow">箭头函数</a>:</p>
<pre><code class="javascript">setTimeout(() =>
{
console.log("Hello, Fundebug!");
}, 100)</code></pre>
<p>由于低版本的浏览器没有支持ES6语法,这就意味着代码会出错。例如,在IE 10浏览器中,会出现"语法错误":</p>
<p><img src="/img/bVbce0h?w=268&h=78" alt="图片描述" title="图片描述"><br>如果你使用了<a href="https://link.segmentfault.com/?enc=KV16sy8p2RSlgEu7AruYpg%3D%3D.zH20zUHI2v5SCr4kIchfWC7wqvOWkGQkNAz%2FF679ncs%3D" rel="nofollow">Fundebug</a>错误监控服务,则会收到这样的报错:</p>
<p><img src="/img/bVbce0g?w=1502&h=600" alt="图片描述" title="图片描述"></p>
<h3>直接使用babel转码</h3>
<p>当你使用更高版本的JavaScript语法时,比如ES7,低版本的浏览器将无法运行。为了兼容低版本的浏览器,比如万恶的IE,我们不得不使用<a href="https://link.segmentfault.com/?enc=PD1ScFM4ZEjiPRrvrRT0Bw%3D%3D.KKt6UyKY%2Fw1nRPurUP1LKuT1hSRBrB6fSNMQxyCZkI8%3D" rel="nofollow">Babel</a>,将ES6、ES7等高版本代码转换为ES5代码。</p>
<h4>安装<a href="https://link.segmentfault.com/?enc=Gr%2F6VAx8RakEqz9%2FGIHwpQ%3D%3D.soxiN9OdU2BgnovF2MnGYbnXdvHNQ74U8UUEX7BlmEKjzKFJ%2Fw8u8P0FD50cYHEM" rel="nofollow">babel-cli</a>
</h4>
<pre><code class="bash">sudo npm install --global babel-cli</code></pre>
<h4>使用babel命令转码</h4>
<pre><code class="bash">babel test.js --out-file compiled.js</code></pre>
<p>转码之后生成的代码为<a href="https://link.segmentfault.com/?enc=4MLPhTYVaLFzjPo9GiSJXw%3D%3D.0P%2FxoKyIxPxJwclV%2BRd0OtmjN%2F1YwsIUb2BW40PbVGoWdR78ftOdMLgJIeNExJxUbU2hUtF9jaxmAGbw7b7pTC8QPi6z7W2GYqSxhwpQzxw%3D" rel="nofollow">compiled.js</a>:</p>
<pre><code class="javascript">setTimeout(function () {
console.log("Hello, Fundebug!");
}, 100);</code></pre>
<p>可知,箭头函数转换成了function,这样就代码可以在IE 10等不支持ES6的浏览器上正确执行了。</p>
<p><em>广告:欢迎免费试用<a href="https://link.segmentfault.com/?enc=u6FKnBFgiqE0KeyK96bGFw%3D%3D.eramIkR06XwChuzbNU86J%2FcgzeQrFHbK%2BLr%2FUaCz88g%3D" rel="nofollow">Fundebug</a>,助您第一时间发现代码BUG。</em></p>
<h3>使用webpack运行Babel</h3>
<p>一般项目中都会使用<a href="https://link.segmentfault.com/?enc=%2B3yGwDD7JPzgBV7i0OoVWQ%3D%3D.fqhYgk%2FYew8Wgz3PW8urETJ7lrHWIQZ7FjvuUJ9TjA4%3D" rel="nofollow">webpack</a>对代码进行打包,比如,将多个js文件打包成1个js文件,这样可以减少前端的资源请求。因此,我们需要将Babel也集成到webpack中。</p>
<h4>安装webpack</h4>
<pre><code class="bash">npm install --global webpack</code></pre>
<p>我使用的webpack版本为4.10.0</p>
<pre><code class="bash">webpack --version
4.10.0</code></pre>
<h4>安装babel</h4>
<pre><code class="bash">npm install --save-dev babel-cli babel-preset-env</code></pre>
<p><a href="https://link.segmentfault.com/?enc=KgIrUwv8ILNtxSb7gUSxhg%3D%3D.OOi66LjW0kFj9J6oLv87Fl35Yo7XC4auFHZ0qe2tPydIO4sIboBkYXMm%2BC5ZmzvP" rel="nofollow">babel-preset-env</a>是Babel新版的preset,它可以让我们<a href="https://link.segmentfault.com/?enc=BnAi6aiNp82sFZIe3GCBZA%3D%3D.PUEDa2f03JM9hyMpW8QadgCnSbgNAOYYk3mky62EXQVMu4jCN%2BC9ifqlBS4%2B2eN3" rel="nofollow">灵活地设置代码目标执行环境</a>,比如只支持各个浏览器最新的2个版本,支持IE8及其以上的IE浏览器。</p>
<h4>安装babel-loader</h4>
<pre><code class="bash">npm install --save-dev babel-loader</code></pre>
<p><a href="https://link.segmentfault.com/?enc=9nzGkyxDaC5H%2F5wQsedOzA%3D%3D.jPuLnDMITEwWNObVm0fVSOugD0D9lucj58Zzzs%2FMop8l86XoLMMYboiREDBCTiNk" rel="nofollow">babel-loader</a>是webpack的babel插件,它让我们可以在wepback中运行Babel。</p>
<h4>配置babel</h4>
<p>新增<a href="https://link.segmentfault.com/?enc=HrvOj9fDg4kAxXw%2B6vR9xg%3D%3D.WNg1mkHZN%2BTfBuLOTLPDHQsYIfFcXn4%2BD7RUAMVEHCbAH6PorI4ty0HkKxGIE%2BmS8eFqqrjXEj8pnzvnPlsBf8sttvyCnY8gM21sjccg19o%3D" rel="nofollow">.babelrc</a>文件:</p>
<pre><code class="leaf">{
"presets": ["env"]
}</code></pre>
<h4>配置webpack</h4>
<p>新增<a href="https://link.segmentfault.com/?enc=z4%2BZd%2Be6qiC9Lyr39PtAZA%3D%3D.WSzQFnIXsQJEBBby4m9KX8XCSFKMT%2FChYSyu1bAq91GQbkmFB12zUWeyu%2BBxCRTeSZgKOGCcAZqiunk2gUiLadv0jOh9zMdWFez7PxGZzJaWsjalo%2BLHxNrXVD44piBh" rel="nofollow">webpack.config.js</a>文件:</p>
<pre><code class="javascript">module.exports = {
entry: './test.js',
output:
{
path: __dirname,
filename: 'bundle.js'
},
module:
{
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
}
};</code></pre>
<p>可知,我们在webpack中使用了babel-loader插件来运行Babel,转换所有的.js代码(除了node_modules中的代码)。</p>
<h4>使用webpack运行babel</h4>
<pre><code class="bash">webpack --mode production</code></pre>
<p>转换之后的代码为<a href="https://link.segmentfault.com/?enc=xoIotXLP4hAEvnjGtxQLzw%3D%3D.MKXJYQxy6Rv28yBAeMuvy8n51jolsCvPqaWVYyF9SaUo63uif6N5Zx8p5EqPIZw%2BMmK5NvIkOxoO3sjPJPaXeQI7P5UXo9BQ7BgxpAYxeIA%3D" rel="nofollow">bundle.js</a>。bundle.js只有1行代码,这是因为为我们指定的mode为production,webpack为了压缩代码只生成了1行代码。</p>
<h3>参考</h3>
<ul>
<li><a href="https://link.segmentfault.com/?enc=eaXMME0XaHYYwp%2FMnFWBRg%3D%3D.BSCNnprAXklbZtiioJeqQOUe17zb3MkNQctFOy%2BfnLLHKPn2KTO5SXf2DRCLYfxDVw%2BmAnutl8wJ8DKn27x9Hw%3D%3D" rel="nofollow">webpack 配合babel 将es6转成es5 超简单实例</a></li>
<li><a href="https://link.segmentfault.com/?enc=O6Yn0KuKLRgKf2QRZRcXAw%3D%3D.akTJuHrELb304cNi9hufo%2BxFhaMNPXEBKWSMk9TP4yhjHxqY8fX42FJQG6LfGrmfl1%2BBqGc85Og18NK5%2FnbxXg%3D%3D" rel="nofollow">Babel入门教程</a></li>
<li><a href="https://link.segmentfault.com/?enc=mxuWkUGYtr9h20voX1Nyhg%3D%3D.XNx%2F1%2FQKXWNJ0kHZl1fm6DrIqASzzzlCmYuyOy31v7T6uO29Irml3Z8a7mCO1BzH" rel="nofollow">babel-preset-env: a preset that configures Babel for you</a></li>
</ul>
<h3>关于Fundebug</h3>
<p><a href="https://link.segmentfault.com/?enc=E0y1BUlej8M%2BMY0qIxqxdw%3D%3D.hzVi1f4q%2BIhW7z%2B%2BTB3KyEbL8uSlXoW6mO4HcL30NOE%3D" rel="nofollow">Fundebug</a>专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!</p>
<p><img src="/img/remote/1460000016656970?w=400&h=225" alt="" title=""></p>
<h3>版权声明</h3>
<p>转载时请注明作者<a href="https://link.segmentfault.com/?enc=kgZ9pi9w4FjNlrP92SZVPQ%3D%3D.NDR1YYziDFr0AY3AQo35Q%2F%2F2PZ3rQBkwkDV8SGeBw0g%3D" rel="nofollow">Fundebug</a>以及本文地址:<br><a href="https://link.segmentfault.com/?enc=Omk1q2nXk4w6btVoN2SMYw%3D%3D.OomdUKf950TokYmtT3wjlmuEP45%2BkUx0MzPddBJbNSmu9Ki0xV6Kvs%2B9ExxVf1laR59LmDUR5v%2BrFNbpmMrzzQ%3D%3D" rel="nofollow">https://blog.fundebug.com/2018/06/13/webpack-babel-tutorial/</a></p>