首页
Search
1
解决 docker run 报错 oci runtime error
49,335 阅读
2
WebStorm2025最新激活码
27,569 阅读
3
互点群、互助群、微信互助群
22,731 阅读
4
常用正则表达式
21,540 阅读
5
罗技鼠标logic g102驱动程序lghub_installer百度云下载windows LIGHTSYNC
19,320 阅读
自习室
CODER
课程
SEO
学习视频
手册资料
呆萌
工具软件
运维
DBA
互通有无
资源
微信群
激活工具
搞钱日记
养生记
包罗万象
登录
Search
标签搜索
DeepSeek
学习指北
Prompt
提示词
Loong
累计撰写
179
篇文章
累计收到
0
条评论
首页
栏目
自习室
CODER
课程
SEO
学习视频
手册资料
呆萌
工具软件
运维
DBA
互通有无
资源
微信群
激活工具
搞钱日记
养生记
包罗万象
页面
搜索到
143
篇与
的结果
2019-06-13
mysql 根据经纬度计算距离并排序
mysql 根据经纬度计算距离并排序。计算公式是这样的: Lng1表示A点纬度和经度,Lat2 Lng2 表示B点纬度和经度a = Lat1 – Lat2为两点纬度之差 b = Lng1 -Lng2 为两点经度之差6378.137为地球半径,单位为公里计算出来的结果单位为公里SELECT *, ( 2 * 6378.137 * ASIN( SQRT( POW( SIN( PI() * (111.86141967773438 - lng) / 360 ), 2 ) + COS(PI() * 33.07078170776367 / 180) * COS(lat * PI() / 180) * POW( SIN( PI() * (33.07078170776367 - lat) / 360 ), 2 ) ) ) ) AS juli FROM `area` ORDER BY juli ASC LIMIT 0, 20;PHP计算经纬度方法:/** * @desc 根据两点间的经纬度计算距离 * @param float $lat 纬度值 * @param float $lng 经度值 */ function getDistance($lat1, $lng1, $lat2, $lng2) { $earthRadius = 6367000; $lat1 = ($lat1 * pi() ) / 180; $lng1 = ($lng1 * pi() ) / 180; $lat2 = ($lat2 * pi() ) / 180; $lng2 = ($lng2 * pi() ) / 180; $calcLongitude = $lng2 - $lng1; $calcLatitude = $lat2 - $lat1; $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2); $stepTwo = 2 * asin(min(1, sqrt($stepOne))); $calculatedDistance = $earthRadius * $stepTwo; return round($calculatedDistance); }
2019年06月13日
10,210 阅读
0 评论
146 点赞
2019-06-06
软著申请资料模板示例及申请地址
提取码:x2ur 点击以上链接下载软件著作权申请的资料模板以及表格填写说明等资料。中国版权登记系统:http://apply.ccopyright.com.cn/cpcc/column_list_bqdj.jsp软件著作权即软件开发者、软件所有者对软件享有发表权,使用权等权利,但是享有权利前应到相关部门进行登记申报,看是否符合法定的要求。 请使用IE浏览器,否则提交著作权登记申请的时候可能会遇到无法提交的问题。
2019年06月06日
13,215 阅读
0 评论
203 点赞
2019-05-17
常用银行sql表(含银行标识)及银行logo
提取码:94th 常用银行sql表(含银行标识)及银行logoCREATE TABLE `bank` ( `id` int(11) NOT NULL AUTO_INCREMENT, `bank_name` varchar(20) NOT NULL COMMENT '银行名称', `bank_code` varchar(11) NOT NULL COMMENT '银行标识码', PRIMARY KEY (`id`), KEY `bank_name` (`bank_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2019年05月17日
15,567 阅读
0 评论
158 点赞
2019-05-17
通过酷Q实现qq机器人,实现qq客服、定时推送qq消息、群管理等功能
通过酷Q实现qq机器人,实现qq客服、定时推送qq消息、群管理等功能。方式:1.windows下载酷Q并安装http-api插件。 下载地址:https://pan.baidu.com/s/1qY55zp62.直接使用docker,通过wine运行在linux系统上。$ docker pull richardchien/cqhttp:latest $ mkdir coolq # 用于存储酷 Q 的程序文件 $ docker run -ti --rm --name cqhttp-test \ -v $(pwd)/coolq:/home/user/coolq \ # 将宿主目录挂载到容器内用于持久化酷 Q 的程序文件 -p 9000:9000 \ # noVNC 端口,用于从浏览器控制酷 Q -p 5700:5700 \ # HTTP API 插件开放的端口 -e COOLQ_ACCOUNT=123456 \ # 要登录的 QQ 账号,可选但建议填 -e CQHTTP_POST_URL=http://example.com:8080 \ # 事件上报地址 -e CQHTTP_SERVE_DATA_FILES=yes \ # 允许通过 HTTP 接口访问酷 Q 数据文件 richardchien/cqhttp:latest其中,CQHTTP_POST_URL、CQHTTP_SERVE_DATA_FILES 是用于配置插件运行的,格式为「CQHTTP_ + 插件配置项的大写」,具体的配置项,见 配置。然后访问 http://注意,默认情况下,容器启动时会检查是否已经存在 config 目录,如果不存在,则会将 CQHTTP_ 开头的环境变量写入到配置文件中;如果 config 目录存在,即不是首次启动,则不会做任何修改。因此,你可以在容器运行时手动修改配置文件,重启容器后仍然有效,这和旧版本的行为不一样!如果你要让容器每次启动时都使用环境变量重新创建配置文件,以保持插件行为和容器启动命令的一致性,可以设置环境变量 FORCE_ENV 的值为 true。完成上述配置后即可通过调用api完成qq的发送消息及qq群管理等功能,剩下的具体的业务逻辑使用自己熟悉的语言去实现即可。详细的接口文档:https://richardchien.gitee.io/coolq-http-api/附点餐小呆萌代码:/** * 接收事件上报 * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function receive(){ try{ $getData = input('post.') ? : file_get_contents('php://input'); if (!empty($getData['group_id']) && (int)$getData['group_id'] == $this->groupId) { if ($this->userId = $this->getGroupUserid()){ $content = $getData['raw_message'] ? : $getData['message']; //分离酷q的前置数据与内容文本 preg_match('/(.*[CQ:]{3}.*[]]{1})(.*)/u', $content, $arr); if (!empty($arr[1]) && !empty($arr[2])){ //提取前置数据中被@的qq号 preg_match('/(.*[CQ:at,qq=]{9})([0-9]{5,11})([]]{1})/u', $arr[1], $arr1); if (!empty($arr1[2]) && (int)$arr1[2] == 167114078){ //来到这里证明是被at了,取得纯文本内容进行下一步处理 $tasks = db("group_task") ->whereTime('create_time', 'today') ->select(); if (count($tasks)>=2){ preg_match_all("/([周]{1})([一二三四五六日]{1}).{0,3}([a-cA-C]{1}|[\u{4e0d}]{1}[\u{70b9}]{1})/u", $arr[2],$arr8); $dateArr = $this->getLastSevenDays(); if (!empty($arr8[2])) { //有选项 $data = []; //获取任务id与时间的对应数组,用于判断用户输入的时间有没有任务 $taskArr = array_column($tasks, 'id', 'time'); foreach ($arr8[2] as $key => $value) { $data[strtotime($dateArr[$this->changeDateType($value)])] = $arr8[3][$key]; if (!empty($taskArr[strtotime($dateArr[$this->changeDateType($value)])])){ $taskId = $taskArr[strtotime($dateArr[$this->changeDateType($value)])]; $this->order($taskId, $arr8[3][$key]); }else{ $this->sendGroup($this->groupId, "{$this->groupUserInfo['user_name']}周{$value},没有可点套餐。"); } } }else{ //无选项 preg_match('/([不]{1}[点]{1})/u', $arr[2],$arr2); preg_match('/([A-Ca-c])/u', $arr[2], $arr3); if (!empty($arr2[0]) && $arr2[0] == "不点" || !empty($arr3[0]) && in_array(ucfirst($arr3[0]), ['A', 'B', 'C'])){ $lists = []; $listsNote = []; foreach ($tasks as $v){ $lists[] = "周".$this->changeDateType((int)date("w", $v['time'])); $listsNote[] = "周".$this->changeDateType((int)date("w", $v['time'])) . "-A"; } $msg = "大佬,今天要点" . count($tasks) ."天的餐,你这样我不知道你想点哪一个呀。". PHP_EOL ."今日可点餐有" . implode('、', $lists) . ",点餐请按示例格式回复。". PHP_EOL ."如:" . implode(' ', $listsNote); $this->sendGroup($this->groupId, $msg); } } }else{ if (!empty($tasks[0]['id'])){ preg_match('/([不]{1}[点]{1})/u', $arr[2],$arr2); preg_match('/([A-Ca-c])/u', $arr[2], $arr3); if (!empty($arr2[0]) && $arr2[0] == "不点") { $this->order($tasks[0]['id'], $arr2[0]); exit; }else if (!empty($arr3[0]) && in_array(ucfirst($arr3[0]), ['A', 'B', 'C'])) { $this->order($tasks[0]['id'], ucfirst($arr3[0])); exit; }else { //$this->sendGroup($this->groupId, "不要@我,大佬不给我说话!"); exit; } } } } } } exit; } }catch (\Exception $e){ Log::write("Receive message:".$e->getMessage()); } } /** * 发送消息 * 多行内容部分记得urlencode * @param bool $toUserId * @param bool $content */ public function send($toUserId = false, $content = false){ if ($toUserId && $content){ $content = urlencode($content); $url = "http://127.0.0.1:5701/send_private_msg?user_id={$toUserId}&message={$content}"; file_get_contents($url); } } /** * 发送群消息 * @param bool $groupId * @param bool $message */ public function sendGroup($groupId = false, $message = false){ if ($groupId && $message){ $message = urlencode($message); $url = "http://127.0.0.1:5701/send_group_msg?group_id={$groupId}&message={$message}"; file_get_contents($url); } } /** * 获取群用户id * @return bool|mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ private function getGroupUserid(){ $userModel = db('group_user'); $userInfo = $userModel->where(['qq'=>$this->params['user_id']])->find(); if (isset($userInfo['id'])){ if ((int)$userInfo['status']!=1) return false; $this->groupUserInfo = $userInfo; return $userInfo['id']; } $userParam = $this->params['sender']; $userInfo = [ 'qq' => $userParam['user_id'], 'user_name' => $userParam['nickname'], 'age' => $userParam['age'], 'sex' => $this->getSex($userParam['sex']), 'create_time' => time(), 'update_time' =>time() ]; $this->groupUserInfo = $userInfo; return $userModel->insertGetId($userInfo) ? : false; } private function order($taskId='', $type=''){ try { $type = ucfirst($type); $task = db("group_task") ->find($taskId); if ($task) { $dbModel = db('group_order'); $record = $dbModel ->where([ 'user_id' => $this->userId, 'task_id' => $task['id'] ]) ->find(); $msg = "{$this->groupUserInfo['user_name']},"; if ($record) { $result = $dbModel->update([ 'id' => $record['id'], 'task_id' => $task['id'], 'type' => $this->changeOrderType($type), 'update_time' => time() ]); $msg .= "更新点餐成功,"; } else { $result = $dbModel->insert([ 'user_id' => $this->userId, 'task_id' => $task['id'], 'type' => $this->changeOrderType($type), 'create_time' => time() ]); $msg .= "点餐成功,"; } if ((int)$this->changeOrderType($type) == 9) { $date = $this->changeDateType((int)date("w", $task['time'])); $msg = "{$this->groupUserInfo['user_name']},好的知道了,你周{$date}不点。"; }else if ($result) { $data = json_decode($task['data'], true); $msg .= "您点的是:{$type}餐,【{$data[$type]}】。"; }else{ $msg = "哦吼,点餐失败,系统出错了。"; } $this->sendGroup($this->groupId, $msg); }else{ $this->sendGroup($this->groupId, "{$this->groupUserInfo['user_name']},还没到点餐时间,到时间会通知你的,认真上班吧。"); } }catch (\Exception $e){ $this->sendGroup($this->groupId, "卡bug了,错误信息:".$e->getMessage().'line:'.$e->getLine()); } } /** * 添加点餐任务 * @return mixed */ public function add_task(){ if (request()->isPost()){ $content = input('post.content'); //提取文本中的日期 preg_match_all("'\d{1,2}月\d{1,2}'", $content,$arr1); $time = empty($arr1[0][0]) ? time() : strtotime(date('Y') . '/' . str_replace(['月'], '/', $arr1[0][0])); $dbModel = db("group_task"); $where = [ 'time' => $time ]; $check = $dbModel->where($where) ->find(); if ($check){ $date = date('Y年m月d日', $time); $this->error("{$date},该日期已存在订餐任务,不能重复添加!"); } preg_match_all('/([A-Za-z#].+)/u', $content,$arr); if (!empty($arr[1])) { $result = []; foreach ($arr[1] as $v){ $v = preg_replace("/(\s|\ \;| |\xc2\xa0)/","",$v); $data = explode('餐',$v); if (!empty($data[0]) && in_array($data[0], ['A', 'B', 'C']) && !empty($data[1])) { $result[$data[0]] = $data[1]; } } if (count($result)>=3) { $data = [ 'time' => $time, 'data' => json_encode($result, JSON_UNESCAPED_UNICODE), 'content' => $content, 'create_time' => time() ]; $dbModel->insert($data); $this->success('添加点餐任务成功!'); } } $this->error('添加任务失败!'); exit; } return $this->fetch(); } /** * 推送qq消息 */ public function push_message(){ if (request()->isPost()) { $content = input('post.content'); $this->sendGroup($this->groupId, $content); //$this->sendGroup($this->groupId, "来活了,老铁们,开始点餐啦,A、B、C随便选,不点的回复不点,点餐时需要先@小助手,否则不管用哦,点餐12点准时结束,过时不候。"); $this->success("推送成功!"); } return $this->fetch(); } /** * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function views(){ $userModel = db('group_user'); $day = input("param.day") ? : (date('d')); $startTime = strtotime(date("Y-m-{$day} 00:00:00")); $task = db("group_task") ->where(['time'=> $startTime]) ->find(); $data = empty($task['id'])? [] : $userModel->alias('u') ->field("u.id,u.user_name,o.type,o.create_time") ->join("group_order o", "o.task_id = {$task['id']} and o.user_id = u.id", 'LEFT') ->where(['u.status' => 1]) ->order("o.type asc") ->select(); $result = $this->array_group_by($data, 'type'); $notChoose = isset($result['']) ? implode(',', array_column($result[''], 'user_name')) : ''; $this->assign('not_choose', $notChoose); ksort($result); $record = []; $msg = []; foreach ($result as $k => $v){ if (!empty((int)$k) && in_array((int)$k, [1,2,3])){ $num = count($v); $msg[] = $this->changeOrderType($k) ." {$num}份"; $record[$k] = $num; } } $info = '云商项目开发部: '.implode(', ', $msg) . " 共计:".array_sum($record) . "份"; foreach ($data as $k => &$v){ if (!empty($v['type']) && in_array((int)$v['type'], [1, 2, 3])){ $v['status'] = 1; }else{ $v['status'] = ''; } $v['type'] = $this->changeOrderType($v['type']); if ($v['create_time']){ $v['create_time'] = date('Y-m-d H:i:s', $v['create_time']); } } krsort($msg); if (request()->isPost()){ $result = [ 'code' => 0, 'data' => $data ]; echo json_encode($result); exit; } if ($task){ $task = json_decode($task['data'], true); } $days = date('t', strtotime('Y-m')) + 1 ; $this->assign('days', $days); $this->assign('day', $day); $this->assign('task', $task); $this->assign('data', $data); $this->assign('info', $info); return $this->fetch(); } /** * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function view_month(){ $days = date('t', strtotime('2019-03')); $userModel = db('group_user'); $orderModel = db('group_order'); $month = input("param.month") ? : date('m'); if (request()->isPost()){ $startTime = strtotime(date("Y-{$month}-1")); $endTime = strtotime(date("Y-m-d", strtotime("last day of this month", strtotime(date("Y-{$month}-d"))))); $data = $userModel ->field("id,user_name") ->where(['status' => 1]) ->select(); foreach ($data as &$v){ $results = $orderModel->alias('o')->field("t.time") ->join('group_task t', "t.id = o.task_id", "LEFT") ->where([ 'o.user_id' => $v['id'], 't.time' => ['between', [$startTime, $endTime]], 'o.type' => ['IN', [1,2,3]] ])->select(); $v['type'] = "午餐"; $timeArr = array_column($results, 'time'); for ($i=1;$i 0, 'data' => $data ]; echo json_encode($result); exit; } $this->assign('months', [1,2,3,4,5,6,7,8,9,10,11,12]); $this->assign('month', $month); return $this->fetch(); } public static function array_group_by($arr, $key) { $grouped = []; foreach ($arr as $value) { $grouped[$value[$key]][] = $value; } if (func_num_args() > 2) { $args = func_get_args(); foreach ($grouped as $key => $value) { $parms = array_merge([$value], array_slice($args, 2, func_num_args())); $grouped[$key] = call_user_func_array('array_group_by', $parms); } } return $grouped; } /** * 点餐结束,推送点餐情况 * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function push_order_result(){ if (!empty($this->params['token']) && $this->params['token'] == $this->push_token) { $task = db("group_task") ->whereTime('create_time', 'today') ->select(); if ($task) { $userModel = db('group_user'); $msg = '今日点餐时间结束,点餐情况如下:'.PHP_EOL; foreach ($task as $v){ $orderDate = date('Y年m月d日', $v['time']); $msg .= "用餐时间:{$orderDate}".PHP_EOL; $data = $userModel->alias('u') ->field("u.id,u.user_name,o.type,o.create_time") ->join('group_order o', "o.user_id = u.id and task_id = {$v['id']}", 'LEFT') ->where(['u.status' => 1]) ->select(); $orderData = json_decode($v['data'], true); foreach ($data as $vo){ if (!empty($vo['type']) && in_array((int)$vo['type'], [1,2,3])){ $type = $this->changeOrderType($vo['type']); $msg .= "{$vo['user_name']} : {$type}餐 【{$orderData[$type]}】".PHP_EOL; }else{ $msg .= "{$vo['user_name']} : 不点".PHP_EOL; } } $result = $this->array_group_by($data, 'type'); $typeMsg = []; $record = []; foreach ($result as $k => $v){ if (!empty((int)$k) && in_array((int)$k, [1,2,3])){ $num = count($v); $typeMsg[$k] = $this->changeOrderType($k) ." {$num}份"; $record[$k] = $num; } } ksort($typeMsg); $msg .= PHP_EOL."{$orderDate} 云商项目开发部: ".implode(', ', $typeMsg) . " 共计:".array_sum($record) . "份".PHP_EOL; } $this->sendGroup($this->groupId, $msg); } } } /** * 开饭前推送今天的点餐情况 * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function push_today_order(){ if (!empty($this->params['token']) && $this->params['token'] == $this->push_token) { $task = db("group_task") ->whereTime('time', 'today') ->find(); if ($task){ $userModel = db('group_user'); $orderDate = date('m月d日', $task['time']); $msg = "下班开饭,{$orderDate}点餐情况如下,请对号入座:".PHP_EOL; $data = $userModel->alias('u') ->field("u.id,u.user_name,o.type,o.create_time") ->join('group_order o', "o.user_id = u.id and task_id = {$task['id']}", 'LEFT') ->where(['u.status' => 1]) ->select(); $orderData = json_decode($task['data'], true); foreach ($data as $vo){ if (!empty($vo['type']) && in_array((int)$vo['type'], [1,2,3])){ $type = $this->changeOrderType($vo['type']); $msg .= "{$vo['user_name']} : {$type}餐 【{$orderData[$type]}】".PHP_EOL; }else{ $msg .= "{$vo['user_name']} : 不点".PHP_EOL; } } //$msg .= PHP_EOL."你喜欢岁月静好,其实现实是大江奔流。"; $this->sendGroup($this->groupId, $msg); } } } /** * 获取未来7天分别是周几 * @param bool $time * @return array */ public function getLastSevenDays($time = false){ if (!$time) $time = time(); $data = []; for ($i=0;$i<7;$i++){ $data[date('w', $time)] = date('Y-m-d 00:00:00', $time); $time += 60*60*24; } return $data; } /** * 把中文的周几转换为数字并对应php date()方法 * @param string $date * @return bool|int */ public function changeDateType($date = ''){ $result = false; if (is_int($date)){ switch ($date){ case 1: $result = '一'; break; case 2: $result = '二'; break; case 3: $result = '三'; break; case 4: $result = '四'; break; case 5: $result = '五'; break; case 6: $result = '六'; break; case 0: $result = '日'; break; } }else{ if (empty($date)) return $result; switch ($date){ case '一': $result = 1; break; case '二': $result = 2; break; case '三': $result = 3; break; case '四': $result = 4; break; case '五': $result = 5; break; case '六': $result = 6; break; case '日': $result = 0; break; } } return $result; }
2019年05月17日
7,442 阅读
0 评论
46 点赞
2019-05-11
centos 搭建Nginx 负载均衡
搭建Nginx 负载均衡一、安装如下环境yum -y install make gcc gcc-c++ gcc-g77 flex bison file libtool libtool-libs autoconf kernel-devel libjpeg libjpeg-devel libpng libpng-devel libpng10 libpng10-devel gd gd-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glib2 glib2-devel bzip2 bzip2-devel libevent libevent-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel gettext gettext-devel ncurses-devel gmp-devel pspell-devel unzip libcap lsof编译pcre的包tar zxf pcre-8.31.tar.gzcd pcre-8.31./configuremake && make installuseradd -s /sbin/nologno -g nginx -M nginxtar zxf nginx-1.10.2.tar.gzcd nginx-1.10.2./configure –prefix=/usr/local/nginx –sbin-path=/usr/local/nginx/bin/nginx –conf-path=/usr/local/nginx/conf/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx/nginx.pid –lock-path=/var/lock/nginx.lock –user=nginx –group=nginx –with-http_ssl_module –with-http_flv_module –with-http_stub_status_module –with-http_gzip_static_module –http-client-body-temp-path=/var/tmp/nginx/client/ –http-proxy-temp-path=/var/tmp/nginx/proxy/ –http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ –http-uwsgi-temp-path=/var/tmp/nginx/uwsgi –http-scgi-temp-path=/var/tmp/nginx/scgi –with-pcremakemake install/usr/local/nginx/bin/nginx –t./nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory 解决prce的问题 #find / -name libpcre.so*/usr/local/lib/libpcre.so.1.0.1/usr/local/lib/libpcre.so/usr/local/lib/libpcre.so.1/lib64/libpcre.so.0.0.1/lib64/libpcre.so.0出现了这么多结果。我们安装的PCRE库的位置在/usr/local/pcre中,我们就用这个位置vim /etc/ld.so.conf在尾行加入/usr/local/binroot@mail2 bin]# ldconfig#/usr/local/nginx/bin/nginx -tnginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is oknginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful 这就正常了启动nginx/usr/local/nginx/bin/nginxvim /usr/local/nginx/conf/nginx.conf在最后面的大括号前面添加一行include /usr/local/nginx/conf.d/*.conf;建立这个目录mkdir /usr/local/nginx/conf.dvim /usr/local/nginx/conf.d/lkq.confupstream backend{server 192.168.236.150:80 weight=1;server 192.168.236.151:80 weight=2;#ip_hash;}server{listen 80;server_name www.lkq.com;location ~ ^/*{proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_buffering off;proxy_pass http://backend;}}haproxy+nginx实现高可用负载均衡Keepalived 的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除, 当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的 web服务器。HAProxy 提供高可用性、负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy 特别适用于那些负载特大的 web 站点, 这些站点通常又需要会话保持或七层处理。HAProxy 运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整 合进您当前的架构中, 同时可以保护你的 web 服务器不被暴露到网络上。系统环境: CenOS 6.5x86_64 Desktop install 将selinux and iptables 设置为disabled图1 为基本的架构图:图2 为IP地址分配。主要用途IPHaproxy+keepalived_master192.168.236.143Haproxy+keepalived_backup192.168.236.192Webser1192.168.236.150Webser2192.168.236.151一:安装过程,在两台HA机器上分别keepalived:#ln -s /usr/src/kernels/2.6.18-128.el5-i686/ /usr/src/linux http://www.keepalived.org/software/ keepalived 的下载地址。版本的话自己可以选择一下版本。楼主选择的版本是1.2.23的版本 [root@mail2 keepalived-1.2.23]# ./configure –sysconf=/etc [root@mail2 keepalived-1.2.23]# make && make install [root@mail2 keepalived-1.2.23]# ln –s /usr/local/sbin/keepalived /sbin [root@mail2keepalived-1.2.23]#cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak [root@mail4keepalived-1.2.23]# ln -s /etc/init.d/keepalived /etc/rc.d/rc3.d/S99keepalived [root@mail4keepalived-1.2.23]# ln -s /etc/init.d/keepalived /etc/rc.d/rc5.d/S99keepalived二、修改配置文件Director server 1 的配置文件[root@Lserver-1 keepalived]# cat keepalived.confMaster :! Configuration File for keepalived vrrp_script chk_http_port { script "/etc/keepalived/check_haproxy.sh" ######设置了一个keepalived一个脚本 interval 2 weight 2 global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER ###keepalived 的主 interface eth0 virtual_router_id 51 priority 150 #####keepalived 一个ID 号 备的ID一定要小于主的ID advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_http_port } virtual_ipaddress { 192.168.236.230 ######一个VIP地址 } } }BACKUP:! Configuration File for keepalived vrrp_script chk_http_port { script "/etc/keepalived/check_haproxy.sh" #####一个keepalived的脚本同主一样 interval 2 weight 2 global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP ####为keepalived 的backup 备节点 interface eth0 virtual_router_id 51 priority 120 ####### keepalived 的一个ID号,一定要小于主节点 advert_int 1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_http_port } virtual_ipaddress { 192.168.236.230 ##同主 } } }三、Master 主机上:####这里是一个控制haproxy的一个启动脚本 #vi /etc/keepalived/check_haproxy.sh #!/bin/bash A=`ps -C haproxy --no-header | wc -l` if [ $A -eq 0 ];then /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg echo "haproxy start" sleep 3 if [ `ps -C haproxy --no-header | wc -l`-eq 0 ];then /etc/init.d/keepalived stop echo "keepalived stop" fi fiBackup 备机上:#!/bin/bash A=`ip a | grep 192.168.236.230 | wc -l` B=`ps -ef | grep haproxy | grep -v grep| awk '{print $2}'` if [ $A -gt 0 ];then /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg else kill -9 $B fi#两台机器分别执行:chmod 755 /etc/keepalived/check_haproxy.sh四、haproxy的安装(主备都一样):yum -y install pcre pcre-devel wget https://fossies.org/linux/misc/haproxy-1.7.5.tar.gz tar xf haproxy-1.7.5.tar.gz cd haproxy-1.7.5 make TARGET=linux26 ARCH=x86_64 PREFIX=/usr/local/haproxy USE_PCRE=1 make install PREFIX=/usr/local/haproxy #cd/usr/local/haproxy/ #mkdir conf #mkdir logs#vi haproxy.cfgglobal log 127.0.0.1 local0 log 127.0.0.1 local1 notice #log loghost local0 info maxconn 4096 # chroot /usr/share/haproxy chroot /usr/local/haproxy uid 99 gid 99 daemon #debug #quiet defaults log global mode http option httplog option dontlognull retries 3 #redispatch maxconn 2000 option redispatch stats uri /haproxy stats auth admin:admin frontend www bind *:80 acl web hdr(host) -i www.lkq.com ####这里是通过域名访问的。如果域名为这个则通过。 use_backend webserver if web backend webserver #webserver作用域 mode http balance roundrobin option httpchk /index.html server s1 192.168.236.151:80 weight 3 check ###这两条记录为后端的两台WEB服务器 server s2 192.168.236.150:80 weight 3 check五、:先主后从,两台机器上都分别启动:/etc/init.d/keepalivedstart (如果之前没有启动haproxy,这条命令会自动把haproxy启动)[root@Rserver-1 conf]# ps -ef |grep haproxy nobody 14766 1 0 19:13 ? 00:00:01 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg root 16034 8237 0 19:56 pts/2 00:00:00 grep haproxy [root@Rserver-1 conf]# ps -ef |grep keepalived root 16016 1 0 19:56 ? 00:00:00 keepalived -D root 16018 16016 0 19:56 ? 00:00:00 keepalived -D root 16019 16016 0 19:56 ? 00:00:00 keepalived -D root 16102 8237 0 19:56 pts/2 00:00:00 grep keepalived [root@Rserver-1 conf]#六、再两台HA上分别执行ip addr list |grep 192.168.23master:[root@Rserver-1 conf]# ip addr list |grep 192.168.236 inet 192.168.236.143/24 brd 192.168.236.255 scope global eth0 inet 192.168.236.230/32 scope global eth0 [root@Rserver-1 conf]#Backup:[root@Lserver-1 keepalived]# ip addr list |grep 192.168.236 inet 192.168.236.192/24 brd 192.168.236.255 scope global eth0 [root@Lserver-1 keepalived]#七、停掉主上的haproxy,3秒后keepalived会自动将其再次启动[root@Rserver-1 conf]# killall haproxy [root@Rserver-1 conf]# ps -ef |grep haproxy nobody 14766 1 0 19:13 ? 00:00:02 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg root 16826 8237 0 20:01 pts/2 00:00:00 grep haproxy八、停掉主的keepalived,备机马上接管服务Master:[root@Rserver-1 conf]# /etc/init.d/keepalived stop [root@Rserver-1 conf]# ip addr list|grep 192.168.236 inet 192.168.236.143/24 brd 192.168.236.255 scope global eth0 [root@Rserver-1 conf]#Backup:[root@Lserver-1 keepalived]# ip addr list|grep 192.168.236 inet 192.168.236.192/24 brd 192.168.236.255 scope global eth0 inet 192.168.236.230/32 scope global eth0 [root@Lserver-1 keepalived]#
2019年05月11日
12,097 阅读
0 评论
14 点赞
1
...
24
25
26
...
29