做服务端,最重要的就是服务稳定性,服务稳定性方面又分为两个方面。一个是发生前,如何降低事故发生的频率,甚至避免事故的发生。另一个是发生后,如何及时发现异常指标,在系统宕掉之前处理,快速止损。任何一个互联网大公司,各种系统的监控都是很完善的,有机器维度的监控、业务指标维度的监控等,甚至各个子系统也可能会有一些监控。这就造成了另外一个问题。一旦发生业务指标的报警,需要连VPN,然后看好多地方的曲线是否正常,甚至还要看天气情况,有没有什么活动(天气和重大活动对打车有较大影响),当地运营商网络情况,对于新人往往不那么友好。

那么,需求就来了。

NO. 1:能不能做一个模块,在业务指标产生异常触发报警时候,把各个需要人工看的地方自动截图一下,发到群里呢?

NO. 2:或者是做一个简单页面,把各个监控聚合到一个地址里。报警之后,自动发送链接到群里,值班人员直接点击链接就可以看各个模块的指标呢?

NO. 3:再或者是做一个模块,获取容易影响当前报警指标的各个因素的数据,然后自动分析出可能原因,每次报警之后自动给出结论呢?

技术总是来源于生活,回归于生活。这一下子就产生了三个目标,当然最简单的就是前两个,属于短平快的项目,今天就介绍前两个吧,后面那个是长期目标。

01

网页登录和截屏 

网页抓取和内容分析,估计大家都知道怎么搞,各种爬虫框架都有现成的方法,语言自带的http请求方法也很容易做到内容的抓取。但是截屏怎么搞,怎么截取网页内容渲染后的结果?最简单就是复用浏览器自身的渲染流程,在浏览器渲染出内容之后,想办法触发截屏操作,当然还要控制浏览器。废话不多说,直接上正题吧。
 
不知道大家有没有听过selenium webdriver。这个东西可以让你用代码控制浏览器,简直如臂使指。可以打开指定URL,可以往文本框里直接塞入账号密码,可以直接向某个元素发送点击事件,这不就搞定登录了吗,是不是So easy. 不止于此,还可以获取DOM元素,还可以等待一些事件(比如页面title的变化,某些元素的变化等等)。利用这个可以搞好多事情,最重要的是完全是通过浏览器运行模拟出来,比直接自己通过http请求不知道高明多少倍。看下图,感受下。

 

而且webdriver有很多语言版本,PHP里有facebook的php-webdriver(https://github.com/facebook/php-webdriver),python里直接安装selenium就行。然后还要安装chrome浏览器,当然也可以用其他浏览器。官网上还要安装chrome driver 和 selenium-server-standalone。稍微有些麻烦,这个不用管它了,直接安装一个webdriver-manager,三条命令就搞定了。

npm install -g webdriver-manager
webdriver-manager update

webdriver-manager start

还是比较简单的,剩下的就是代码部分了。

首先就是先创建一个driver,driver里有一些参数,可以设置窗口大小。headless是无头模式,可以隐藏浏览器界面,否则会打开浏览器界面,调试时候用这个比较方便。

$host = 'http://localhost:4444/wd/hub';
$disiredCapabilities = DesiredCapabilities::chrome();
$currentChromeOptions = $disiredCapabilities->getCapability(ChromeOptions::CAPABILITY);
$chromeOptions = !empty($currentChromeOptions) ? $currentChromeOptions : new ChromeOptions();
$chromeOptions->addArguments(['window-size=1024,768', 'headless']);
$disiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);
$driver = RemoteWebDriver::create($host, $disiredCapabilities);

然后就可以打开页面,进行截图了。

$driver->get("http://www.baidu.com");
sleep(2);
$driver->takeScreenshot(文件存储路径);

这个是强制休眠了2秒,等待页面加载完毕。比较low,你可以用wait操作,等待一些条件的触发。until里面会循环检测condition是否满足,一直到你设置的超时时间。WebDriverExpectedCondition里还有一些其他条件,可以挖掘一下。

$webDriverCondition = WebDriverExpectedCondition::titleIs("登录");
$driver->wait(2)->until($webDriverCondition);

你可以通过下面的代码查找文本框,然后输入用户名密码,进行登录。如果有验证码,可以安装其他识别验证码的库,获取到验证码的url,然后进行识别。

$driver->findElement(WebDriverBy::id('username'))->sendKeys(用户名);
$driver->findElement(WebDriverBy::id('password'))->sendKeys(密码);
$driver->findElement(WebDriverBy::id('submit'))->click();

整体用法还是比较简单的,短短几行代码就实现了登录和截屏,剩下的就是通过一些钉钉机器人的一些API进行发送了。接下来搞一下聚合多个外部网页的功能,这个也比较简单,直接用html写就行了。

02

外部网页聚合

这个没什么好说的,直接用bootstrap的Nav导航栏,结合iframe就可以了,iframe的高度需要设置一下。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>网页聚合</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript">
             $(function () { 
                 $('#alarm-tab a').click(function (e) { 
                        e.preventDefault();
                        $(this).tab('show');
                        
                 });
            });

             function reinitIframe(){
                    var iframes = document.getElementsByName("alarm-frame");
                    try{
                        for(i = 0; i < iframes.length; i++) {
                            iframe = iframes[i];
                            var tabHeight = document.getElementById("alarm-tab").offsetHeight;
                            var windowHeight = $(window).height();
                            var height = windowHeight - tabHeight;
                            iframe.height = height;
                            console.log(height);
                        }
    
                    }catch (ex){
                        console.log(ex);
                    }
            }

            reinitIframe();
            window.setInterval("reinitIframe()", 200);
    </script>
</head>
<body width="100%" height="100%">

<ul class="nav nav-pills nav-justified" id="alarm-tab">
  <li class="active"><a href="#baidu">BaiDu</a></li>
  <li><a href="#google">Google</a></li>
</ul>

<div class="tab-content"> 
      <div class="tab-pane active" id="baidu" width="100%" height="100%">
          <iframe name="alarm-frame" src="http://www.baidu.com" width="100%" height="100%"></iframe>
      </div> 
      <div class="tab-pane" id="google" width="100%" height="100%">
          <iframe name="alarm-frame" src="http://www.google.com" width="100%" height="100%"></iframe>
      </div> 
</div> 

</body>
</html>

这个比较简单,不多说了,但是感觉可以搞一个简单的服务,让用户把多个感兴趣的网页聚合起来,生成一个统一的URL。

本篇文章来源于微信公众号: 搞点儿啥

最后修改日期:2019年12月25日

留言

头像

Long time reader, first time commenter — so, thought I’d drop a comment..
— and at the same time ask for a favor.

Your wordpress site is very simplistic – hope you don’t mind me asking what theme you’re
using? (and don’t mind if I steal it? :P)

I just launched my small businesses site –also built
in wordpress like yours– but the theme slows (!) the site down quite a bit.

In case you have a minute, you can find it by
searching for “royal cbd” on Google (would appreciate
any feedback)

Keep up the good work– and take care of yourself during the coronavirus scare!

~Justin

    头像

    The theme is “Mynote”.I think you can optimized your site with CDN,and remove some unused plugins.You can also debug your site in chrome,help you finding out which request slow down your site.

头像

Hello! I justified would like to cede a mammoth thumbs up during the gargantuan info you comprise here on this post. I will be coming isolated to your blog against of more soon. http://www.surviv-io.fun

头像

Excellent way of telling, and pleasant piece of writing to take
data about my presentation subject, which i am going to convey in institution of higher
education.

填写回复或留言