Top Menu

如何利用Vultr的API自动更换故障主机

Vultr的Reserved IP要$3/month,Additional IPv4 IP要$2/month,实在是消费不起,手动更换烦了,遂写了个自动程序,来自动更换主机。

想法是这样的,利用定时任务,每隔5分钟检查一次tcp连接状态,3次异常之后,开始进行切换操作。

切换流程

  1. 获取主机列表
  2. 停用故障主机
  3. 创建故障主机快照
  4. 创建新主机
  5. 用故障主机快照恢复新主机
  6. 删除故障主机

测试通过自动化操作,15分钟内自动确认TCP异常,1小时之内就可以自动切换到新主机。

技术细节

在切换过程中有部分操作需要等待执行完成,比如创建快照和从快照恢复,所以使用了swich来进行步骤计数并写入json文件,初始json计数为0,每操作成功一步,增加一位数。好处是当后一步发现之前的结果出错时可以很灵活的进行回滚。

Vultr的API有一个坑,虽然在创建主机的时候提供了snapshot的选项,但是并不会使用这个snapshot创建主机,导致创建出的主机都是毛坯的,还以为是快照出错了。所以还得分成两步,先创建一个空白主机,再从快照恢复,不过恢复后会自动启动主机,这样就少了一个启动的步骤也算是人性化。

在CLI执行ping命令的时候由于会一直ping下去,程序会进入死循环,在命令前加上timeout就可以限制命令执行时间,不过很可惜,在php中执行命令并没有用。

公用函数

注意替换高亮行的API-Key、缓存路径

function callAPI($method, $url, $data){ $curl = curl_init(); switch ($method){ case "POST": curl_setopt($curl, CURLOPT_POST, 1); if ($data) curl_setopt($curl, CURLOPT_POSTFIELDS, $data); break; case "PUT": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); if ($data) curl_setopt($curl, CURLOPT_POSTFIELDS, $data); break; default: if ($data) $url = sprintf("%s?%s", $url, http_build_query($data)); } // OPTIONS: curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'API-Key: your_vultr_api_key', )); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // EXECUTE: $result = curl_exec($curl); if(!$result){ $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); return $httpcode; } curl_close($curl); return $result; } if ( ! function_exists( 'array_key_last' ) ) { function array_key_last( $array ) { $key = NULL; if ( is_array( $array ) ) { end( $array ); $key = key( $array ); } return $key; } } if (!function_exists('array_key_first')) { function array_key_first(array $array) { if (count($array)) { reset($array); return key($array); } return null; } } function output_json($step){ $outputArray['step'] = $step; $outputJSON = json_encode($outputArray); $fp = fopen('data_auto_swap_ip_vultr.json', 'w') or die("Unable to open file!"); fwrite($fp, $outputJSON); fclose($fp); } function load_json(){ if(file_exists("data_auto_swap_ip_vultr.json")){ $load_json = file_get_contents("data_auto_swap_ip_vultr.json"); }else{ $load_json = '{"step":0}'; echo 'Can not Load last process status, will reset to: '.$load_json; echo "\n"; } return json_decode($load_json, true); }

Continue Reading 0

支付异常检查过程

最近有用户遇到支付成功但是订单却显示已关闭的情况,下面是一系列检查和寻找原因的过程

查看支付代码

  • PaymentController.php
  • YzyController.php
  • AutoJob.php
  • AutoAuditOrders.php

由于版本比较老,所以AutoAuditOrders.php还没有合并到AutoJob.php

搜索log,发现如下异常信息

[2019-01-08 17:09:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:10:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:11:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:12:02] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:13:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:14:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:15:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:16:04] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:17:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:18:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:19:02] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:20:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:21:04] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type [2019-01-08 17:22:03] local.INFO: 【有赞云】审计订单时更新支付单和订单异常:Undefined index: pay_type

Continue Reading 0

Powered by WordPress. Designed by WooThemes