首页 文章 精选 留言 我的

精选列表

搜索[搭建],共10000篇文章
优秀的个人博客,低调大师

2018-04-21 搭建Python官方文档翻译环境

参考PEP 545 -- Python Documentation Translations fork的编译脚本: nobodxbodon/docsbuild-scripts, 添加了zh语言标签, 以及fork的PO文件库nobodxbodon/python-docs-ko, 仅作演示用(更改字段"测试python入门教程": Update index.po · nobodxbodon/python-docs-ko@00b8073) 据非常有限的理解, 大概过程是, PO文件包含了所有翻译的段落, 像打补丁似地附加到原英文文档后生成rEst格式文件, 再编译成HTML文档(html库地址:nobodxbodon/py36zh. 演示: 4. 기타 제어 흐름 도구 - Python 3.6.5 文档) 接下去要解决的是, 如何汉化程序部分, 效果如下. 所有现有的其他语言的翻译文档都没有对程序进行本地化(字符串/命名等) 现在可以通过直接修改rst文件, 但PEP 545的流程是修改PO文件. 问了其他翻译组的作者, 似乎需要修改Sphinx配置才能实现(在PO文件中添加程序部分, 并且在构建时合并入rst文件). 另: Python官方文档(入门教程只是一小部分)日语翻译进度86+%, 法语30%, 中文1.5%: The Python 3.6 translation project on Transifex. 后得知早先有老版本3.2.2的中文翻译项目: https://docspy3zh.readthedocs.io/en/latest/ 不知是否是这1.5%的前身.

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

kubernetes 使用NFS搭建动态存储卷(PV/SorageClass/PVC)

在日常学习测试kubernetes时,经常需要PersistentVolume把一些数据(例如:数据库、日志等)存储起来,不随着容器的删除而丢失;关于PV、PVC、StorageClass的关系参考PV/PVC/StorageClass;存储卷的实现有很多种,此处选择比较容易实现的NFS作为存储;参考了网上好多资料,但都是不太完整,按照资料上的说明操作都有问题,所以在参考了众多资料之后决定记录一下过程,以供各位参考。 环境: centos-7(3.10.0-957.5.1.el7.x86_64)(node1, node2) kubernetes v1.13.0 helm v2.12.0 安装环境 安装kubernetes、helm 参考资料,在node1、node2上安装kubernetes和helm; 安装NFS 在node1上安装NFS Server $ sudo yum -y install nfs-utils rpcbind 在服务端node1上配置共享目录 $ sudo mkdir /var/nfs $ sudo su //切换到root用户 $ echo "/var/nfs 192.168.0.0/24(rw,async,no_root_squash,no_all_squash,sync)" >> /etc/exports //配置共享目录 $ exit //退回原来用户 $ exportfs -r //让上面的配置生效 在服务端启动NFS服务 //必须先启动rpcbind服务,再启动nfs服务,这样才能让nfs服务在rpcbind服务上注册成功 $ sudo systemctl start rpcbind $ sudo systemctl start nfs-server 检查服务是否启动成功 $ showmount -e localhost Export list for localhost: /var/nfs 192.168.0.0/24 设置开机启动 $ sudo systemctl enable rpcbind $ sudo systemctl enable nfs-server 在客户端node2安装nfs-utils **注意:所有kubernetes机器都需要安装nfs-utils,我就是没有在客户端安装nfs-utils,才卡在怎么测试PV、StorageClass、PVC都不通; $ sudo yum install nfs-utils 可以参考资料,在客服端上测试NFS共享存储; NFS作为动态存储卷 参考资料,在node1上使用helm安装NFS-Client Provisioner $ helm install stable/nfs-client-provisioner --set nfs.server=x.x.x.x --set nfs.path=/exported/path --name nfs-client-provisioner 它会安装一个StorageClass $ kubectl get sc NAME PROVISIONER AGE nfs-client cluster.local/nfs-client-provisioner 32h 设置默认StorageClass 使用PVC的时候需要创建并指定PV;如果没有创建PV,就会使用默认的StorageClass来创建相应的PV;否则PVC一直都是Pending的状态; 把上面创建StorageClass设置为默认的 $ kubectl patch storageclass nfs-client -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' $ kubectl get sc NAME PROVISIONER AGE nfs-client (default) cluster.local/nfs-client-provisioner 32h 现在你可以尽情使用PVC了,而不用在去手动创建PV和StorageClass了; 参考资料(谢谢各位作者): https://blog.csdn.net/jettery/article/details/72722324 https://www.kubernetes.org.cn/4956.html https://www.kubernetes.org.cn/4022.html https://blog.51cto.com/passed/2160149 https://blog.51cto.com/fengwan/2176889 https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client https://k8smeetup.github.io/docs/tasks/administer-cluster/change-default-storage-class/

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

基于Spark的机器学习实践 (三) - 实战环境搭建

0 相关源码 1 Spark环境安装 ◆ Spark 由scala语言编写,提供多种语言接口,需要JVM ◆ 官方为我们提供了Spark 编译好的版本,可以不必进行手动编译 ◆ Spark安装不难,配置需要注意,并且不一定需要Hadoop环境 下载 解压 tar zxvf spark-2.4.1-bin-hadoop2.7.tgz 2 Spark配置 ◆ 在配置前尽量先阅读官方文档,避免直接从网上找配置教程 ◆ 要为节点设 置好使用的内存,否则可能导致节点利用率低; ◆ 注意spark中IP与端口号的配置,以免UnknownHostException [官网配置]() 应用默认配置 配置文件 复制两份模板,开启自行配置 单机环境配置 本地IP shell进行验证 bin/spark-shell 3 Spark shell ◆ Spark shell是一个bash脚本,在

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

docker-compose快速搭建 Prometheus+Grafana监控系统

一、说明Prometheus负责收集数据,Grafana负责展示数据。其中采用Prometheus 中的 Exporter含:1)Node Exporter,负责收集 host 硬件和操作系统数据。它将以容器方式运行在所有 host 上。2)cAdvisor,负责收集容器数据。它将以容器方式运行在所有 host 上。3)Alertmanager,负责告警。它将以容器方式运行在所有 host 上。完整Exporter列表请参考:https://prometheus.io/docs/instrumenting/exporters/ 二、安装docker,docker-compose2.1 安装docker先安装一个64位的Linux主机,其内核必须高于3.10,内存不低于1GB。在该主机上安装Docker。 # 安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加Docker软件包源 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装Docker CE yum install docker-ce -y # 启动 systemctl start docker # 开机启动 systemctl enable docker # 查看Docker信息 docker info 2.2 安装docker-compose curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose 三、添加配置文件 mkdir -p /usr/local/src/config cd /usr/local/src/config 2.1 添加prometheus.yml配置文件,vim prometheus.yml # my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: ['192.168.159.129:9093'] # - alertmanager:9093 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: - "node_down.yml" # - "first_rules.yml" # - "second_rules.yml" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' static_configs: - targets: ['192.168.159.129:9090'] - job_name: 'cadvisor' static_configs: - targets: ['192.168.159.129:8080'] - job_name: 'node' scrape_interval: 8s static_configs: - targets: ['192.168.159.129:9100'] 2.2 添加邮件告警配置文件添加配置文件alertmanager.yml,配置收发邮件邮箱vim alertmanager.yml global: smtp_smarthost: 'smtp.163.com:25' #163服务器 smtp_from: 'tsiyuetian@163.com' #发邮件的邮箱 smtp_auth_username: 'tsiyuetian@163.com' #发邮件的邮箱用户名,也就是你的邮箱 smtp_auth_password: 'TPP***' #发邮件的邮箱密码 smtp_require_tls: false #不进行tls验证 route: group_by: ['alertname'] group_wait: 10s group_interval: 10s repeat_interval: 10m receiver: live-monitoring receivers: - name: 'live-monitoring' email_configs: - to: '1933306137@qq.com' #收邮件的邮箱 2.3 添加报警规则添加一个node_down.yml为 prometheus targets 监控vim node_down.yml groups: - name: node_down rules: - alert: InstanceDown expr: up == 0 for: 1m labels: user: test annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes." 四、编写docker-composevim docker-compose-monitor.yml version: '2' networks: monitor: driver: bridge services: prometheus: image: prom/prometheus container_name: prometheus hostname: prometheus restart: always volumes: - /usr/local/src/config/prometheus.yml:/etc/prometheus/prometheus.yml - /usr/local/src/config/node_down.yml:/etc/prometheus/node_down.yml ports: - "9090:9090" networks: - monitor alertmanager: image: prom/alertmanager container_name: alertmanager hostname: alertmanager restart: always volumes: - /usr/local/src/config/alertmanager.yml:/etc/alertmanager/alertmanager.yml ports: - "9093:9093" networks: - monitor grafana: image: grafana/grafana container_name: grafana hostname: grafana restart: always ports: - "3000:3000" networks: - monitor node-exporter: image: quay.io/prometheus/node-exporter container_name: node-exporter hostname: node-exporter restart: always ports: - "9100:9100" networks: - monitor cadvisor: image: google/cadvisor:latest container_name: cadvisor hostname: cadvisor restart: always volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro ports: - "8080:8080" networks: - monitor 五、启动docker-compose #启动容器: docker-compose -f /usr/local/src/config/docker-compose-monitor.yml up -d #删除容器: docker-compose -f /usr/local/src/config/docker-compose-monitor.yml down #重启容器: docker restart id 容器启动如下: prometheus targets界面如下: 备注:如果State为Down,应该是防火墙问题,参考下面防火墙配置。 prometheus graph界面如下: 备注:如果没有数据,同步下时间。 六、防火墙配置6.1 关闭selinux setenforce 0 vim /etc/sysconfig/selinux 6.2 配置iptables #删除自带防火墙 systemctl stop firewalld.service systemctl disable firewalld.service #安装iptables yum install -y iptables-services #配置 vim /etc/sysconfig/iptables *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [24:11326] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 9090 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 3000 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 9093 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 9100 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT #启动 systemctl restart iptables.service systemctl enable iptables.service 七、配置Grafana7.1 添加Prometheus数据源 2 配置dashboards 说明:可以用自带模板,也可以去https://grafana.com/dashboards,下载对应的模板。 7.3 查看数据我从网页下载了docker相关的模板:Docker and system monitoring,893输入893,就会加载出下面的信息 导入后去首页查看数据 八、附录:单独命令启动各容器 #启动prometheus docker run -d -p 9090:9090 --name=prometheus \ -v /usr/local/src/config/prometheus.yml:/etc/prometheus/prometheus.yml \ -v /usr/local/src/config/node_down.yml:/etc/prometheus/node_down.yml \ prom/prometheus # 启动grafana docker run -d -p 3000:3000 --name=grafana grafana/grafana #启动alertmanager容器 docker run -d -p 9093:9093 -v /usr/local/src/config/config.yml:/etc/alertmanager/config.yml --name alertmanager prom/alertmanager #启动node exporter docker run -d \ -p 9100:9100 \ -v "/:/host:ro,rslave" \ --name=node_exporter \ quay.io/prometheus/node-exporter \ --path.rootfs /host #启动cadvisor docker run \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest

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

网络直播系统的架构,基础版直播间搭建

直播行业从2013年发展至今,行业逐步规范,功能逐步增加,前几天,斗鱼直播平台宣布自己又获得了一轮融资,此次融资金额近40亿,那么大家想不想知道网络直播系统的架构呢?本文将从三个版块讲述一个简单的网络直播系统的架构是怎么样的,不说废话,开始吧 一、首页部分 网络直播系统的首页大致会有这么几个模块:顶部/底部导航、分类列表、推荐列表 1、顶部/底部导航 顶部/底部导航通常会有这样几项菜单:关注、直播、视频、附近 、排行、搜索、个人等 1) 关注:用户注册后,点击进入该菜单可以看到自己关注的主播的动态信息,点击直播信息可以直接进入直播间内观看直播 2) 直播列表:在该列表中会有所有在线直播的主播直播间缩略图,通常会依据一定算法(依据推荐值、曝光量。粉丝数等数据计算)排列。 3) 视频列表:主播发布的短视频可以在此处看到,点击进入短视频页面,还可双击点赞、评论留言,该功能被用于主播与用户正在非直播时间内进行社交活动。 4) 附近功能:利用定位系统,计算用户与其它开启定位功能的主播之间的距离,以实现社交活动。 5) 排行榜功能:该功能中可能会有多个榜单,如收益榜、贡献榜等,每个榜单下会有小榜单如“日榜”“月榜”“周榜”等 6) 搜索列表:点击搜索即可出现一个二级页面,在搜索框中输入用户的名字、ID 号或主播房间号可以搜索该用户或直播间 7) 个人菜单点开可进入个人列表 2、分类列表 在分类列表中通常会有音乐、舞蹈、交友、美食等诸多分类,点击进去可精准查询到自己喜欢的直播类型。 3、热门模块 被推荐的直播间会在此显示,推荐值根据“热门礼物”、“粉丝数目”等指数设定,各直播系统推荐机制各不相同。 二、 直播间内 直播房间的类型(付费房间、密码房间、普通房间和计时收费房间等)会在直播间外的缩略图中标明,点击进入直播间,我们可以看到这样一些功能: 1)抢红包功能:用户、主播皆可发布红包,发布红包的数额、是否延迟发送都可以在网络直播系统中进行设置,此功能作用为炒热气氛。 2)发礼物功能:该功能是直播常见的功能,该功能不但能期待如红包一般的热气氛功能,还能适当增加平台、主播的收入。 3)主播连麦功能:主播可以与直播连麦和PK,也可以与观众连麦聊天,该功能配合密码房间可实现一对一直播的功能,也可以作为主播与用户联络感情用,用法多多。 4)关注功能:点击即可关注主播 5)查看榜单功能:主播在本场直播中所收到的礼物、谁为主播打赏了多少钻石,都可在这里看到。 6)发私信功能:用户可使用该功能与主播互发私信 7)直播游戏功能:主播开启该功能,可与用户在线玩游戏 三、 个人主页 在个人主页中,我们可以看到用户直播的次数、发布的短视频、关注的人数和粉丝、充值明细、商城购买物品和家族所属等明细,还可进行个性设置如“在线免打扰”之类的。 如此,一个简单的网络直播系统的架构就这么出来了,如果想增添新功能,也可在此基础上进行二次开发,增加新功能,更多与网络直播系统开发相关的资讯和分析会在以后逐渐放出,敬请期待,需要的朋友请关注我。 声明:文章为原创内容,转载请注明我的博客链接及作者

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

基于Zero-Ice搭建的物联网监控平台

[P1]项目初始态势 开始接手项目时,领导要求很简单,就是做一个本地服务,手机连接上服务,能控制本地系统内的各种设备,至于设备状态如何采集与控制,数据如何分析和存储这里略过,其通信机制类似于下图: ​ 整个项目,领导只安排了只有我一个项目人员,当然能简单就简单。我将本地数据经过转换汇总,终端采用设备-〉信息点的层级关系显示,当然设备层具有自身属性,信息点层也具有自身属性,终端是瘦客户端,在链接上服务端后,由服务端推送层级结构和相关属性信息给客户端,进行初始化,后续就是实现实时上行推送和下行控制,上行和下行采用独立线程处理。 ​ 一个星期后,安装在项目现场,实现了本地WIFI的手机端远程监控,工程人员和使用人员都觉得OK. 又经历一段时间的功能追加,支持各种类型设备可配置接入,支持蓝牙、串口、网络采集数据,支持实时分析与告警,跨平台部署,自动化调度运维等一系列任务,想来项目应该结题。嗯,领导有了新想法。 [P2]项目变种 采用socket通信,手机端需要设置IP,很麻烦,领导希望工程人员、使用人员只要连上WIFI打开app就能实现远程监控。领导发话,没办法只能照办,为了偷懒,当然采用现成的通信机制改造,最终选型了Zero-ice实现,通信机制类似于: ​ 我将的ice配置文件如下: #pragma once #include <Ice/Identity.ice> module PCS { enum DevTypeICE { UDDev=0,Region, Platform,Entity }; enum PTypeICE { UDPInfo=0,YX, YC, YXS, YCS }; struct DateTimeI { int isec; int imsec; }; struct DateTimeS { short year; short month; short day; short hour; short minute; short second; short msec; }; struct PInfo { long pID; string name; string desc; PTypeICE pType; float pValue; }; sequence<PInfo> PInfos; struct Dev { long devID; DevTypeICE devType; string name; string desc; }; sequence<Dev> Devs; interface ClientAchieve { void PValueChange(long devID,long pID, DateTimeI itime, float val); void addDev(Devs devs); void addPInfo(long devID,PInfos pinfos); }; interface ServerAchieve { void AddClient(::Ice::Identity ident); void AddClientID(::Ice::Identity ident,int type); void setPValue(long devID, long pID, float val); }; }; 至于接口实现代码略过,给出部分服务和客户端的通信连接实现参考: 服务端: void PCSServer::listen() { CacheDataObj *ptr_CacheDataObj = CacheDataObj::getInstance(); iceType = ptr_CacheDataObj->getIceType(); confFile = ptr_CacheDataObj->getIceConfFile(); try { Ice::InitializationData initData; initData.properties = Ice::createProperties(); #ifdef ICE_STATIC_LIBS Ice::registerIceSSL(); #endif CLogger::createInstance()->Log(eTipMessage ,"start load ice config file %s", confFile.c_str()); initData.properties->load(confFile); char ** argv; char *p = NULL; argv = &p; int argc = 0; if (iceType > 0) { communicator_ = Ice::initialize(argc, argv, initData); } else { communicator_ = this->communicator(); } if (NULL == communicator_) { CLogger::createInstance()->Log(eConfigError , "communicator initialize fail! [%s %s %d]" , __FILE__, __FUNCTION__, __LINE__); } } catch (const Ice::Exception& ex) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[1]:%s [%s %s %d]" , ex.ice_id().c_str(), __FILE__, __FUNCTION__, __LINE__); disListen(); } catch (const std::string & msg) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[2]:%s [%s %s %d]" , msg.c_str(), __FILE__, __FUNCTION__, __LINE__); disListen(); } catch (const char * msg) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[3]:%s [%s %s %d]" , msg, __FILE__, __FUNCTION__, __LINE__); disListen(); } if (NULL != communicator_) { try { if (iceType > 0) { Ice::ObjectAdapterPtr adapter_pcs = communicator_->createObjectAdapter("SyePcs"); Ice::Identity id_pcs = Ice::stringToIdentity("SyePcs"); PCS::ServerAchievePtr pcs_ = new ServerAchieveI(communicator_); adapter_pcs->add(pcs_, id_pcs); adapter_pcs->activate(); //fprintf(stderr, "ice server listen!\n"); CLogger::createInstance()->Log(eTipMessage, "ice server listen!"); isListen = true; communicator_->waitForShutdown(); } else { Ice::PropertiesPtr properties = communicator_->getProperties(); Ice::ObjectAdapterPtr adapter_pcs = communicator_->createObjectAdapter("SyePcs"); std::string id = communicator_->getProperties()->getPropertyWithDefault("Identity", "PCSIO"); Ice::Identity id_pcs = Ice::stringToIdentity(id); CLogger::createInstance()->Log(eTipMessage , "id_pcs.name=%s", id_pcs.name.c_str()); PCS::ServerAchievePtr pcs_ = new ServerAchieveI(communicator_); adapter_pcs->add(pcs_, id_pcs); adapter_pcs->activate(); CLogger::createInstance()->Log(eTipMessage, "ice server listen!"); isListen = true; communicator_->waitForShutdown(); } } catch (const Ice::Exception& ex) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[1]:%s [%s %s %d]" , ex.ice_id().c_str(), __FILE__, __FUNCTION__, __LINE__); disListen(); } catch (const std::string & msg) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[2]:%s [%s %s %d]" , msg.c_str(), __FILE__, __FUNCTION__, __LINE__); disListen(); } catch (const char * msg) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[3]:%s [%s %s %d]" , msg, __FILE__, __FUNCTION__, __LINE__); disListen(); } catch (...) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception[4]:unkown error for adapter crate and activate! [%s %s %d]" , __FILE__, __FUNCTION__, __LINE__); disListen(); } } else { CLogger::createInstance()->Log(eConfigError , "communicator is NULL! [%s %s %d]" , __FILE__, __FUNCTION__, __LINE__); } }; void PCSServer::disListen() { if (communicator_) { try { isListen = false; communicator_->destroy(); } catch (const Ice::Exception& ex) { CLogger::createInstance()->Log(eSoftError , "Ice::Exception:%s [%s %s %d]" , ex.ice_id().c_str() , __FILE__, __FUNCTION__, __LINE__); } } }; 客户端只给出java的,c++实现类似: import PCS.*; import android.annotation.SuppressLint; import Ice.*; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import java.util.UUID; import java.lang.Thread; @SuppressLint("NewApi") public class PcsClient implements Runnable { public PcsClient() { } boolean connectf=false; InputStream inputStream =null; private Ice.Communicator ic = null; private ServerAchievePrx twoway = null; private ClientAchieveI pca = null; private ObjectAdapter adapter = null; private Ice.Identity ident = null; private boolean mWorking = false; int runType = 1; int clientType = 1; private Thread mythread = null; public void start() { mWorking = true; mythread = new Thread(this); mythread.start(); } @Override public void run(){ long utime = System.currentTimeMillis(); while(mWorking){ try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); break; } if(twoway != null&& pca!=null) { if(System.currentTimeMillis()>(utime+10000)) { // if(!pca.getUpdateState()) { disconnect(); System.out.println("disconnect and connect again"); if(!connect()) { System.out.println("connect 2 fail"); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } utime = System.currentTimeMillis(); // pca.setUpdateState(false); } }else{ if(!connect()) { System.out.println("connect 1 fail"); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } public void stop() { mWorking = false; try { Thread.sleep(1); mythread.interrupt(); //手动停止 mythread.join(); } catch (InterruptedException e) { e.printStackTrace(); } disconnect(); disCommunicator(); } public void disCommunicator() { if (ic != null) { try{ ic.shutdown(); ic.destroy(); ic = null; }catch (Ice.Exception e) { System.out.printf("destroy fail(%s)",e.ice_name()); e.printStackTrace(); } } } public Ice.Communicator getCommunicator() { System.out.println("getCommunicator"); if(ic == null){ Ice.InitializationData initData = new Ice.InitializationData(); System.out.println("InitializationData"); initData.properties = Ice.Util.createProperties(); System.out.println("createProperties"); try { Properties properties = new Properties(); properties.load(inputStream); for (String name : properties.stringPropertyNames()) { String value = properties.getProperty(name); initData.properties.setProperty(name, value); System.out.printf("name=%s,value=%s\n",name,value); } } catch(IOException ex) { String _error = String.format("Initialization failed %s", ex.toString()); System.out.println(_error); try { throw ex; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ic = Ice.Util.initialize(initData); System.out.println("initialize"); if(ic==null){ System.out.println("invalid Communicator"); } } return ic; } public boolean connect() { if(!connectf){ try { twoway = null; if(runType>0){ System.out.println("checkedCast SyePcs.Proxy"); twoway = ServerAchievePrxHelper.checkedCast( getCommunicator().propertyToProxy("SyePcs.Proxy").ice_twoway().ice_secure(false)); }else{ try{ System.out.println("checkedCast PCSIO 1"); twoway = ServerAchievePrxHelper.checkedCast( getCommunicator().stringToProxy("PCSIO").ice_twoway().ice_secure(false).ice_timeout(100)); System.out.println("checkedCast PCSIO 2"); }catch(Ice.NotRegisteredException e){ System.out.println("checkedCast 1 MCSSVCGrid/Query"); Ice.ObjectPrx proxy = getCommunicator().stringToProxy("MCSSVCGrid/Query"); IceGrid.QueryPrx query = IceGrid.QueryPrxHelper.checkedCast(proxy); twoway = ServerAchievePrxHelper.checkedCast( query.findObjectByType("::PCS::PCSIO").ice_twoway().ice_secure(false).ice_timeout(100)); e.printStackTrace(); System.out.println("checkedCast 2 MCSSVCGrid/Query"); } } if(twoway != null) { /*ObjectAdapter*/ adapter = getCommunicator().createObjectAdapter(""); System.out.println("Communicator create adapter"); pca = new ClientAchieveI(); /*Ice.Identity*/ ident = getCommunicator().stringToIdentity("ClientAchieve"); ident = new Ice.Identity(); //System。Guid guid = System。Guid.NewGuid(); //ident.name = guid.ToString(); UUID uuid = UUID.randomUUID(); ident.name = uuid.toString(); //ident.name = java.util.UUID.randomUUID(); ident.category = ""; System.out.println("Communicator get Identity"); adapter.add(pca, ident); adapter.activate(); System.out.println("activate"); twoway.ice_getConnection().setAdapter(adapter); twoway.AddClientID(ident,clientType); System.out.println("AddClient"); connectf = true; pca.setUpdateState(true); }else{ System.err.println("invalid proxy,couldn't find a `::PCS::PCSIO' object"); connectf = false; } } catch (Ice.Exception e) { System.out.println("create Client fail"); e.printStackTrace(); connectf = false; System.out.println("connectf = false"); } } return connectf; } public void disconnect() { if(pca != null){ pca = null; } if(null!=adapter&&null!=ident){ adapter.remove(ident); ident = null; adapter.destroy(); } if(twoway != null){ twoway = null; } connectf = false; } public void setControl(long devID, long pID, float val){ if(twoway != null){ twoway.setPValue(devID, pID, val); } } } 由于本地通信不是很饱和,我只将serverPcs设了一个Node,其简化的application.xml配置如下,serverPcs是按需由节点服务icegridnode启动的: <icegrid> <application name="SyeSys"> <node name="Node01" > <description>测试节点</description> <server id="syePcsSrv" exe="PCS_server" pwd="D:\\SYE_MCS_PRO\\pcs_project\\PCS_server\\x64\\PcsSrv" ice-version="3.6" activation-timeout="60" application-distrib="false" deactivation-timeout="60" activation="on-demand"> <adapter name="SyePcs" id="SyePcs" endpoints="tcp"> <object identity="PCSIO" type="::PCS::PCSIO" property="Identity"/> </adapter> </server> </node> </application> </icegrid> 为了简化与测试,暂时将服务部署本机,后续只要将IP更改即可,并在Host文件将IP与域内自定义站点映射即可,下面以本机地址为例配置了中心服务、节点服务的配置文件,通过节点服务启动serverPcs。 主中心服务配置,一些描述也一并给出,而从中心服务和节点服务只给出配置项: # # The IceGrid instance name. # IceGrid.InstanceName=MCSSVCGrid #1 Ice.Default.Protocol=tcp #Ice.Default.Locator=MCSSVCGrid/Locator:default -p 4061 #2 #1 为这个应用实例指定一个唯一的标识 #2 注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到 # # IceGrid registry configuration. #IceGrid 注册表最多创建四组端点,用下面的属性进行配置: #1)IceGrid.Registry.Client.Endpoints #支持Ice::Locator IceGrid::Query 的客户端端点。 #2)IceGrid.Registry.Server.Endpoints #用于对象和对象适配器注册的服务器端端点。 #3)IceGrid.Registry.Admin.Endpoints #IceGrid::Admin 接口的管理端点( 可选)。 #4)IceGrid.Registry.Internal.Endpoints #定义IceGrid节点用于与注册表进行通信的内部端点内部接口的端点。这些内部端点必须能被IceGrid节点用于与注册表进行通信的内部端点节点访问。 # IceGrid.Registry.Client.Endpoints=default -p 4061 #3 #协议default,其值可通过Ice.Default.Protocol设置,默认是tcp,协议可以设置tcp udp ssll ws wss等 #-h <ip>指定网址,-p <port> 指定端口, -t <msec> 指定超时毫秒数, 多个Endpoint采用':'间隔 #IceGrid.Registry.Client.Endpoints=default -h 127.0.0.1 -p 4061 #3 IceGrid.Registry.Server.Endpoints=default #4 #IceGrid.Registry.Admin.Endpoints=default -p 4062 #IcePack.Registry.Admin.Endpoints=default -p 4062 IceGrid.Registry.Internal.Endpoints=default #5 #IceGrid.Registry.ReplicaName=Master #标识服务名称 #IceGrid.Registry.Data=db\\LMDB_master #6 IceGrid.Registry.LMDB.Path=db\\LMDB_master IceGrid.Registry.DynamicRegistration=1 #IceGrid.Node.CollocateRegistry=1 //定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置,不能有两个节点都配置这个属性只能有一个主Registry配置 # 3 客户端访问注册服务器的端点信息 # 4 服务访问注册服务器的端点信息,通常是default # 5 内部访问端点信息,通常是default,节点用这个端口和注册服务通信 # 6 注册服务的数据目录的路径 # # IceGrid admin clients must use a secure connection to connect to the # registry or use Glacier2. # #IceGrid.Registry.AdminSessionManager.Endpoints=default IceGrid.Registry.PermissionsVerifier=MCSSVCGrid/NullPermissionsVerifier #7 #IceGrid.Registry.CryptPasswords=passwords IceGrid.Registry.AdminPermissionsVerifier=MCSSVCGrid/NullPermissionsVerifier #8 #IceGrid.Registry.SSLPermissionsVerifier=MCSSVCGrid/NullSSLPermissionsVerifier #9 #IceGrid.Registry.AdminSSLPermissionsVerifier=MCSSVCGrid/NullSSLPermissionsVerifier #10 # 7 设定防火墙安全代理,从而控制客户端访问注册表时可用的权限 # 8 设定防火墙安全代理,从而控制注册表管理者可用的权限 # 9 设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制 # 10 设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制 # # IceGrid SQLconfiguration if using SQL database. # #Ice.Plugin.DB=IceGridSqlDB:createSqlDB #11 #IceGrid.SQL.DatabaseType=QSQLITE #12 #IceGrid.SQL.DatabaseName=register/Registry.db #13 # 11 指定Ice对象序列化的机制,如果不设置,默认用Freeze机制 # 12 指定使用数据库的类型 #13 指定使用数据库的名称 # # #Ice Error andStandard output Set # #Ice.StdErr=master/stderr.txt #14 #Ice.StdOut= master/stdout.txt #15 # #14 指定标准错误输出文件 #15 指定标准输出文件 # # Trace properties. # Ice.ProgramName=Master #16 IceGrid.Registry.Trace.Node=2 #17 IceGrid.Registry.Trace.Replica=2 #18 #16 指定主注册服务的名称 #17 指定主注册服务跟踪节点信息的级别(0~3),默认为0 #18 指定主/从热备注册服务的跟踪级别(0~3),默认为0 # # IceGrid nodeconfiguration. # #IceGrid.Node.Name=node_1 #19 #IceGrid.Node.Endpoints=default #20 #IceGrid.Node.Data=node_1 #21 #IceGrid.Node.CollocateRegistry=1 #22 #IceGrid.Node.Output=node_1 #23 #IceGrid.Node.RedirectErrToOut=1 #24 # 19 定义节点的名称,必须唯一 # 20 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default # 21 节点的数据目录的路径 # 22 定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置 # 23 节点标准输出信息重定向蹈的目录路径,会自动生成输出文件 # 24 节点上的服务程序的标准错误重定向到标准输出 # Traceproperties. # IceGrid.Node.Trace.Activator=1 #25 IceGrid.Node.Trace.Adapter=2 #26 IceGrid.Node.Trace.Server=3 #27 # 25 激活器跟踪级别,通常有0,1,2,3级,默认是0 # 26 对象适配器跟踪级别,通常有0,1,2,3级,默认是0 # 27 服务跟踪级别,通常有0,1,2,3级,默认是0 # # Dummy usernameand password for icegridadmin. # IceGridAdmin.Username=mygrid #28 IceGridAdmin.Password=mygrid #29 # 28 IceGrid管理器登录该应用的用户名 # 29 IceGrid管理器登录该应用的密码 从中心服务配置: # The IceGrid locator proxy. #主从注册表之间访问定位器配置 Ice.Default.Locator=MCSSVCGrid/Locator:default -p 4061 #可指定ip #Ice.Default.Locator=MCSSVCGrid/Locator:default -h 127.0.0.1 -p 4061 # IceGrid registry configuration. IceGrid.Registry.Client.Endpoints=default -p 14061 #可指定ip #IceGrid.Registry.Client.Endpoints=default -h 127.0.0.1 -p 14061 IceGrid.Registry.Server.Endpoints=default IceGrid.Registry.Internal.Endpoints=default IceGrid.Registry.ReplicaName=Slave#指定从注册服务的名称 IceGrid.Registry.LMDB.Path=db/LMDB_slave # IceGrid admin clients must use a secure connection to connect to the IceGrid.Registry.PermissionsVerifier=MCSSVCGrid/NullPermissionsVerifier IceGrid.Registry.AdminPermissionsVerifier=MCSSVCGrid/NullPermissionsVerifier # Trace properties. Ice.ProgramName=Slave IceGrid.Registry.Trace.Node=2 IceGrid.Registry.Trace.Replica=2 # Traceproperties. IceGrid.Node.Trace.Activator=1 # Dummy usernameand password for icegridadmin. IceGridAdmin.Username=mygrid #28 IceGridAdmin.Password=mygrid #29 节点服务的配置: # The IceGrid locator proxy. Ice.Default.Locator=MCSSVCGrid/Locator:default -p 4061:default -p 14061 IceGrid.Node.Name=Node01 IceGrid.Node.Endpoints=default IceGrid.Node.Data=db/node_01 IceGrid.Node.Output=db/node_out_01 # Trace properties. Ice.ProgramName=Node IceGrid.Node.Trace.Replica=2 IceGrid.Node.Trace.Activator=1 #log tracing Ice.LogFile=iceserv.log Ice.LogFile.SizeMax=1048576 Ice.PrintStackTraces=2 #Ice.Trace.GC=1 Ice.Trace.Protocol=1 Ice.Trace.Slicing=1 Ice.Trace.Retry=2 Ice.Trace.Network=2 Ice.Trace.Locator=2 #warning Ice.Warn.Connections=1 Ice.Warn.Datagrams=1 Ice.Warn.Dispatch=1 Ice.Warn.AMICallback=1 #Ice.Warn.Leaks=1 配置完成后我们将配置启动脚本,当然也可以通过命令逐个执行,为了便捷,配置数个脚本,以win系统为例: (1)start_center_server.bat,用于启动主从中心服务 start /b /Min "registry01" icegridregistry --Ice.Config=config.master start /b /Min "registry02" icegridregistry --Ice.Config=config.slave (2)start_admin.bat,用于修改更新配置 ::如果更改配置,需要重新映射服务,删除数据目录并重新生成或更新,需先启动中心服务,再调用配置服务更新 ::start_center_server.bat icegridadmin --Ice.Config=config.admin -e "application add 'application.xml'" icegridadmin --Ice.Config=config.admin -e "application update 'application.xml'" (3)start_server.bat,启动节点服务集,本案例只有一个 cd D:\SYE_MCS_PRO\pcs_project\PCS_server\x64\PcsSrv start /b /Min "node01" icegridnode --Ice.Config=config.node cd D:\SYE_MCS_PRO\pcs_project\sye_mcs\mgr (4)stop_server.bat,关闭服务集使用 taskkill /f /im icegridregistry.exe taskkill /f /im icegridnode.exe taskkill /f /im PCS_server.exe 配置完成,先去配置一些服务需要的一些目录, 如 D:\SYE_MCS_PRO\pcs_project\sye_mcs\mgr\db\LMDB_master, D:\SYE_MCS_PRO\pcs_project\sye_mcs\mgr\db\LMDB_slave, D:\SYE_MCS_PRO\pcs_project\PCS_server\x64\PcsSrv\db\node_01, D:\SYE_MCS_PRO\pcs_project\PCS_server\x64\PcsSrv\db\node_out_01, 我手动配置是为了防止尝试配置测试的就数据信息阻隔目录创建或权限受限,完成目录配置后 ,先start_center_server.bat服务,然后启动start_admin.bat(配置有改动时)和start_server.bat。 当服务启动稳定后,serverPcs服务应该是没有启动的,只有客户端连接需求后才会被触发启动。 客户端的ice配置文件config0.client如下: # # The IceGrid locator proxy. #"Ice.Default.Locator"的访问地址与"IceGrid.Registry.Client.Endpoints设置"一致 # Ice.Default.Locator=MCSSVCGrid/Locator:tcp -h localhost -p 4061:tcp -h localhost -p 14061 #Ice.Default.Locator=MCSSVCGrid/Locator:tcp -h www.syemcs.com -p 4061:tcp -h www.pytest.com -p 14061 #非本地连接,需指定IP #Ice.Default.Locator=MCSSVCGrid/Locator:tcp -h 192.168.1.102 -p 4061:tcp -h 192.168.1.102 -p 14061 #Ice.Default.Router=MCSSVCGlacier2/router:tcp -h www.syemcs.com -p 4064:ssl -h www.pytest.com -p 4065 现在启动测试终端,通过从服务-〉节点服务-〉serverPcs,终端与serverPcs建立了长链接: ​​ 手机终端类似下图 ​​ 服务部署到工程上使用了一段时间,领导开始又不满足了,嗯,想在家里也能远程监控现场设备,顺便来个短信告警、统计报表啥的。好吧,准备升级。 [P3]升级到互联网 嗯,这次在利用Zero-Ice比较熟络了,我设计了通信机制如下: ​ 我将本地的serverPcs作为客户端,并在阿里云购买了ECS、数据库等服务,并建立了一个控制中转的门户服务serverMcs来支持各地的serverPcs链接进来,另外建立一个serverDcs来支持互联网终端链接进来,同时将终端升级,将每一个serverPcs推送的数据看作一个区域,即显示格式为区域-〉设备-〉信息点的层级结构。 同样,需要为serverPcs<->serverMcs和app<->serverDcs建立Ice通信接口,其接口文件与本地的终端APP通信类似, McsInterface.ice: #pragma once #include <Ice/Identity.ice> module MCS { //area type for ice communitation enum AreaTypeICE { UDArea=0,ShowingRoom,SubwayStation }; //virtual device type for ice communitation enum DevTypeICE { UDDev=0,Region, Platform,Entity }; //piont type for ice communitation enum PTypeICE { UDPInfo=0,YX, YC, YXS, YCS }; //date time describe by second and millsecond struct DateTimeI { int isec; int imsec; }; //date time describe by the struct within year mon day hour min second millsecond struct DateTimeS { short year; short month; short day; short hour; short minute; short second; short msec; }; //ponit desc struct PInfo { long pID; string name; string desc; PTypeICE pType; float pValue; }; sequence<PInfo> PInfos; dictionary<long, PInfo> PInfoMap; //device desc struct Dev { long devID; DevTypeICE devType; string name; string desc; }; sequence<Dev> Devs; dictionary<long, Dev> DevMap; //area desc struct Area { long areaID; AreaTypeICE areaType; string name; string desc; }; sequence<Area> Areas; sequence<long> AreaIDs; //file comunication format struct FileBinary { string filename; int startpos; int filesize; string filebuf; int buflen; }; //point desc from server and set point value struct PValue { long areaID; long devID; long pID; DateTimeI itime; float val; }; //client accomplish it interface MCSClient { void setPValue(PValue pval); int nextFileData(long areaID,out FileBinary filedata); bool FileRefresh(long areaID,int fileType,string filename); }; //server accomplish it interface MCSServer { void AddClient(::Ice::Identity ident,int type,AreaIDs areaids); void PValueChange(PValue pval); //void addArea(Areas areas); void addArea(Area area); void addDev(long areaID,Devs devs); void addPInfo(long areaID,long devID,PInfos pinfos); }; }; DcsInterface.ice: #pragma once #include <Ice/Identity.ice> module DCS { enum AreaTypeICE { UDArea=0,ShowingRoom,SubwayStation }; enum DevTypeICE { UDDev=0,Region, Platform,Entity }; enum PTypeICE { UDPInfo=0,YX, YC, YXS, YCS }; struct DateTimeI { int isec; int imsec; }; struct DateTimeS { short year; short month; short day; short hour; short minute; short second; short msec; }; struct PInfo { long pID; string name; string desc; PTypeICE pType; float pValue; }; sequence<PInfo> PInfos; struct Dev { long devID; DevTypeICE devType; string name; string desc; }; sequence<Dev> Devs; struct Area { long areaID; AreaTypeICE areaType; string name; string desc; }; sequence<Area> Areas; sequence<long> AreaIDs; interface ClientAchieve { //for internet void PValueChangeI(long areaID,long devID,long pID, DateTimeI itime, float val); void addAreaI(Areas devs); void addDevI(long areaID,Devs devs); void addPInfoI(long areaID,long devID,PInfos pinfos); }; interface ServerAchieve { //for internet void AddClientAreas(::Ice::Identity ident,AreaIDs areaIDList); void setPValueI(long areaID,long devID, long pID, float val); }; }; 其实现逻辑很简单,就是serverPcs只要重新连接上云端后,推送一次设备-〉信息点整个层级结构信息,然后根据业务需要在变化或定期上送信息点数值和接收下行控制,而对于终端来说,也是瘦客户端,其链接上云端后,先根据其订购和账号权限,获得相应的设备及信息点的初始化推送,在终端建立起区域->设备->信息点的层级显示,后续就是刷新服务端推送数据和下发控制。 通信接口函数的具体实现略过,通信链接实现参考本地(java)即可,下面给出c++客户端通信实现代码示例。 int MCSClientV::Run() { while (!exitflag) { if (!m_bConnect) { #ifdef WIN32 Sleep(1000); #else usleep(1000000); #endif if (connect()) { newConnectEvent(); } } else { changeUpEvent(); } #ifdef WIN32 Sleep(10); #else usleep(10000); #endif } return 0; } void MCSClientV::setPValue(const ::MCS::PValue &pval) { if (areaID != pval.areaID) { return; } unsigned long taskID = ptr_ServiceChain->getTaskIDFromDateTime(); PFrom _pfrom; if (ptr_CacheDataObj->getFromInfo(static_cast<unsigned long long>(pval.devID) , static_cast<unsigned int>(pval.pID), _pfrom)) { float _val = pval.val; ptr_CacheDataObj->getCValue(static_cast<unsigned long long>(pval.devID) , static_cast<unsigned int>(pval.pID), _val); WDS wd(_pfrom.ipLong, OnSet, _pfrom.pID, _pfrom.pType, _val, 0, "ICE_Control_MCS", taskID); ptr_ReceiveData->addWDS(wd); CLogger::createInstance()->Log(eControlMessage , "TaskID[%lu] and down_node[1] setPValue from ICE MCS,time(%s)" ",devID(%ld),pID(%ld),val(%.3f)" ",down_control_map, ip[%s],pID(%d),pType(%d),val(%.3f)" , taskID , PFunc::getCurrentTime().c_str() , pval.devID, pval.pID, pval.val , _pfrom.ipStr.c_str() , _pfrom.pID, static_cast<int>(_pfrom.pType), _val); // VerificationCache vit; vit.execTime = PFunc::getCurrentTime("%04d%02d%02dT%02d%02d%02dZ"); vit.taskID = taskID; vit.taskDesc = "ICE_Control_MCS"; vit.devID = static_cast<unsigned long>(pval.devID); vit.devDesc = _pfrom.devDesc; vit.pID = static_cast<unsigned long>(pval.pID); vit.pDesc = _pfrom.pDesc; vit.pType = static_cast<unsigned int>(_pfrom.pType); vit.val = pval.val; vit.limitTimeForCheck = static_cast<unsigned int>(time(NULL)) + 5; vit.eway_ = _pfrom.eway; ptr_VerificationForControlCache->addVerifyData(vit); } else { PValueRet pret(pval.val); ptr_CacheDataObj->setValue(static_cast<unsigned long long>(pval.devID) , static_cast<unsigned int>(pval.pID), pret); CLogger::createInstance()->Log(eControlMessage , "TaskID[%lu] and down_node[1] setPValue from ICE MCS and down_node[0],time(%s)" ",devID(%ld),pID(%ld),val(%.3f)" ",ditect set val to virtual ponit control" , taskID, PFunc::getCurrentTime().c_str() , pval.devID, pval.pID, pret.val_actual); } } bool MCSClientV::FileRefresh(::Ice::Long areaID, ::Ice::Int filetype, const ::std::string &filename) { return false; } ::Ice::Int MCSClientV::nextFileData(::Ice::Long areaID, ::MCS::FileBinary &fdata) { return 0; } Ice::CommunicatorPtr MCSClientV::communicator() { fprintf(stderr, "MCSClientV::communicator()\n"); if (m_ic == NULL) { char ** argv; char *p = NULL; argv = &p; int argc = 0; Ice::InitializationData initData; initData.properties = Ice::createProperties(); #ifdef ICE_STATIC_LIBS Ice::registerIceSSL(); #endif //fprintf(stderr, "load %s start\n", confFile.c_str()); CLogger::createInstance()->Log(eTipMessage , "load %s start" , confFile.c_str()); initData.properties->load(confFile); m_ic = Ice::initialize(argc, argv, initData); } return m_ic; }; bool MCSClientV::connect() { if (!m_bConnect) { try { fprintf(stderr, "MCS::MCSServerPrx::checkedCast\n"); if (runType>0) { soneway = MCS::MCSServerPrx::checkedCast( communicator()->propertyToProxy("SyeMcs.Proxy")->ice_twoway()->ice_secure(true)); } else { try { fprintf(stderr, "checkedCast MCSIO\n"); soneway = MCS::MCSServerPrx::checkedCast( communicator()->stringToProxy("MCSIO")->ice_twoway()->ice_secure(false)); } catch (const Ice::NotRegisteredException&) { fprintf(stderr, "checkedCast MCSLGrid/Query\n"); IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(communicator()->stringToProxy("MCSLGrid/Query")); soneway = MCS::MCSServerPrx::checkedCast( query->findObjectByType("::MCS::MCSIO")->ice_twoway()->ice_secure(false)); } } if (!soneway) { std::cerr <<"couldn't find a `SyeMcs.Proxy' object." << std::endl; } else { std::cerr <<"find a `SyeMcs.Proxy' object." << std::endl; //MCS::MCSServerPrx oneway = twoway->ice_oneway(); //MCS::MCSServerPrx batchOneway = twoway->ice_batchOneway(); //MCS::MCSServerPrx datagram = twoway->ice_datagram(); //MCS::MCSServerPrx batchDatagram = twoway->ice_batchDatagram(); Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter(""); Ice::Identity ident; ident.name = IceUtil::generateUUID(); m_strUUID = ident.name; ident.category = ""; MCS::MCSClientPtr crtwoway = new MCSClientI(this); adapter->add(crtwoway, ident); adapter->activate(); soneway->ice_getConnection()->setAdapter(adapter); ::MCS::AreaIDs aids; aids.push_back(areaID); //flag client-type client-area-ids-map soneway->AddClient(ident,(int)1, aids); m_bConnect = true; } } catch (const Ice::Exception& ex) { //fprintf(stderr, "%s\n", ex.ice_id().c_str()); CLogger::createInstance()->Log(eSoftError , "Ice::Exception[1]:%s, [%s %s %d]" , ex.ice_id().c_str() , __FILE__, __FUNCTION__, __LINE__); } catch (const std::string & msg) { //fprintf(stderr, "%s\n", msg.c_str()); CLogger::createInstance()->Log(eSoftError , "Ice::Exception[2]:%s, [%s %s %d]" , msg.c_str() , __FILE__, __FUNCTION__, __LINE__); } catch (const char * msg) { //fprintf(stderr, "%s\n", msg); CLogger::createInstance()->Log(eSoftError , "Ice::Exception[3]:%s, [%s %s %d]" , msg , __FILE__, __FUNCTION__, __LINE__); } } return m_bConnect; }; void MCSClientV::disconnect() { if (m_bConnect) { m_bConnect = false; } if (NULL!=m_ic) { try { m_ic->destroy(); m_ic = NULL; } catch (const Ice::Exception& ex) { //fprintf(stderr, "%s\n", ex.ice_id().c_str()); CLogger::createInstance()->Log(eSoftError , "Ice::Exception:%s, [%s %s %d]" , ex.ice_id().c_str() , __FILE__, __FUNCTION__, __LINE__); } } } void MCSClientV::newConnectEvent() { ::MCS::Devs _devs; if (ptr_CacheDataObj->getDevsToSrv(_devs)) { try { //::MCS::Areas areas; ::MCS::Area area; area.areaID = areaID; area.areaType = (MCS::AreaTypeICE)areaType; area.name = areaName; area.desc = areaDesc; soneway->addArea(area); // soneway->addDev(areaID,_devs); for (::MCS::Devs::const_iterator itdev = _devs.begin(); itdev != _devs.end(); ++itdev) { ::MCS::PInfos _pinfos; if (ptr_CacheDataObj->getPInfosToSrv(itdev->devID, _pinfos)) { soneway->addPInfo(area.areaID,itdev->devID, _pinfos); } } } catch (...) { //printf("addDev or addPInfo Error:%d\n", static_cast<int>(time(NULL))); CLogger::createInstance()->Log(eSoftError , "addDev or addPInfo Error:%d, [%s %s %d]" , static_cast<int>(time(NULL)) , __FILE__, __FUNCTION__, __LINE__); disconnect(); #ifdef WIN32 Sleep(1000); #else usleep(1000000); #endif } } } void MCSClientV::changeUpEvent() { WDC wdls; // if (ptr_ReceiveData->getFirstWDLS(wdls)) { ::MCS::DateTimeI _itime; _itime.isec = wdls.evtTimeS; _itime.imsec = wdls.evtTimeMS; try { //std::cerr << " PValueChange:" << wdlc.devID << "," << wdlc.pID // << "," << wdlc.val << "," << _itime.isec << "," << _itime.imsec << std::endl; ::MCS::PValue pval; pval.areaID = areaID; pval.devID = wdls.devID; pval.pID = wdls.pID; pval.itime = _itime; pval.val = wdls.val; soneway->PValueChange(pval); } catch (...) { CLogger::createInstance()->Log(eTipMessage , "PValueChange Error:%d [%s,%s,%d]" , static_cast<int>(time(NULL)) , __FILE__, __FUNCTION__, __LINE__); disconnect(); #ifdef WIN32 Sleep(1000); #else usleep(1000000); #endif } if (!ptr_ReceiveData->removeFirstWDLS()) { CLogger::createInstance()->Log(eTipMessage , "removeFirstWDLS Error[%s,%s,%d]" , __FILE__, __FUNCTION__, __LINE__); } } } 下面给出Zero-Ice云端服务的各个配置信息,其实很类似。 application.xml的简要配置: <icegrid> <application name="SyeMSys"> <server-template id="syeMcsSrv"> <parameter name="index"/> <server id="syeMcsSrv-${index}" exe="MCS_server" pwd="D:\\SYE_MCS_PRO\\pcs_project\\MCS_server\\x64\\McsSrv" ice-version="3.6" activation-timeout="60" application-distrib="false" deactivation-timeout="60" activation="on-demand"> <adapter name="SyeMcs" id="SyeMcs-${index}" endpoints="tcp" replica-group="SyeMcsRe"/> <property name="Identity" value="MCSIO"/> </server> </server-template> <replica-group id="SyeMcsRe"> <load-balancing type="random" n-replicas="2"/> <object identity="MCSIO" type="::MCS::MCSIO"/> </replica-group> <node name="Node21"> <description>本地系统门户服务01</description> <server-instance template="syeMcsSrv" index="1"/> <!--server-instance template="syeMcsSrv" index="2"/--> </node> <node name="Node22"> <description>本地系统门户服务02</description> <server-instance template="syeMcsSrv" index="3"/> <!--server-instance template="syeMcsSrv" index="4"/--> </node> <server-template id="syeDcsSrv"> <parameter name="index"/> <server id="syeDcsSrv-${index}" exe="DCS_server" pwd="D:\\SYE_MCS_PRO\\pcs_project\\DCS_server\\x64\\DcsSrv" ice-version="3.6" activation-timeout="60" application-distrib="false" deactivation-timeout="60" activation="on-demand"> <adapter name="SyeDcs" id="SyeDcs-${index}" endpoints="tcp" replica-group="SyeDcsRe"/> <property name="Identity" value="DCSIO"/> </server> </server-template> <replica-group id="SyeDcsRe"> <load-balancing type="random" n-replicas="2"/> <object identity="DCSIO" type="::DCS::DCSIO"/> </replica-group> <node name="Node11"> <description>终端控制门户服务01</description> <server-instance template="syeDcsSrv" index="1"/> </node> <node name="Node12"> <description>终端控制门户服务02</description> <server-instance template="syeDcsSrv" index="3"/> </node> </application> </icegrid> 云端的主从中心服务的配置,测试时以本地为例, config.master: # # The IceGrid instance name. # IceGrid.InstanceName=MCSLGrid #1 Ice.Default.Protocol=tcp #Ice.Default.Locator=MCSLGrid/Locator:default -p 5061 #2 #1 为这个应用实例指定一个唯一的标识 #2 注册服务的端点信息(主注册服务和所有的从注册服务),节点注册时要用到 # # IceGrid registry configuration. #IceGrid 注册表最多创建四组端点,用下面的属性进行配置: #1)IceGrid.Registry.Client.Endpoints #支持Ice::Locator IceGrid::Query 的客户端端点。 #2)IceGrid.Registry.Server.Endpoints #用于对象和对象适配器注册的服务器端端点。 #3)IceGrid.Registry.Admin.Endpoints #IceGrid::Admin 接口的管理端点( 可选)。 #4)IceGrid.Registry.Internal.Endpoints #定义IceGrid节点用于与注册表进行通信的内部端点内部接口的端点。这些内部端点必须能被IceGrid节点用于与注册表进行通信的内部端点节点访问。 # IceGrid.Registry.Client.Endpoints=default -p 5061 #3 #协议default,其值可通过Ice.Default.Protocol设置,默认是tcp,协议可以设置tcp udp ssll ws wss等 #-h <ip>指定网址,-p <port> 指定端口, -t <msec> 指定超时毫秒数, 多个Endpoint采用':'间隔 #IceGrid.Registry.Client.Endpoints=default -h 127.0.0.1 -p 5061 #3 IceGrid.Registry.Server.Endpoints=default #4 #IceGrid.Registry.Admin.Endpoints=default -p 5062 #IcePack.Registry.Admin.Endpoints=default -p 5062 IceGrid.Registry.Internal.Endpoints=default #5 #IceGrid.Registry.ReplicaName=Master #标识服务名称 #IceGrid.Registry.Data=db\\LMDB_master #6 IceGrid.Registry.LMDB.Path=db\\LMDB_master IceGrid.Registry.DynamicRegistration=1 #IceGrid.Node.CollocateRegistry=1 //定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置,不能有两个节点都配置这个属性只能有一个主Registry配置 # 3 客户端访问注册服务器的端点信息 # 4 服务访问注册服务器的端点信息,通常是default # 5 内部访问端点信息,通常是default,节点用这个端口和注册服务通信 # 6 注册服务的数据目录的路径 # # IceGrid admin clients must use a secure connection to connect to the # registry or use Glacier2. # #IceGrid.Registry.AdminSessionManager.Endpoints=default IceGrid.Registry.PermissionsVerifier=MCSLGrid/NullPermissionsVerifier #7 #IceGrid.Registry.CryptPasswords=passwords IceGrid.Registry.AdminPermissionsVerifier=MCSLGrid/NullPermissionsVerifier #8 #IceGrid.Registry.SSLPermissionsVerifier=MCSLGrid/NullSSLPermissionsVerifier #9 #IceGrid.Registry.AdminSSLPermissionsVerifier=MCSLGrid/NullSSLPermissionsVerifier #10 # 7 设定防火墙安全代理,从而控制客户端访问注册表时可用的权限 # 8 设定防火墙安全代理,从而控制注册表管理者可用的权限 # 9 设定SSL安全代理,从而设定客户端访问注册表时的SSL安全访问机制 # 10 设定SSL安全代理,从而设定注册表管理者的SSL安全访问机制 # # IceGrid SQLconfiguration if using SQL database. # #Ice.Plugin.DB=IceGridSqlDB:createSqlDB #11 #IceGrid.SQL.DatabaseType=QSQLITE #12 #IceGrid.SQL.DatabaseName=register/Registry.db #13 # 11 指定Ice对象序列化的机制,如果不设置,默认用Freeze机制 # 12 指定使用数据库的类型 #13 指定使用数据库的名称 # # #Ice Error andStandard output Set # #Ice.StdErr=master/stderr.txt #14 #Ice.StdOut= master/stdout.txt #15 # #14 指定标准错误输出文件 #15 指定标准输出文件 # # Trace properties. # Ice.ProgramName=Master #16 IceGrid.Registry.Trace.Node=2 #17 IceGrid.Registry.Trace.Replica=2 #18 #16 指定主注册服务的名称 #17 指定主注册服务跟踪节点信息的级别(0~3),默认为0 #18 指定主/从热备注册服务的跟踪级别(0~3),默认为0 # # IceGrid nodeconfiguration. # #IceGrid.Node.Name=node_1 #19 #IceGrid.Node.Endpoints=default #20 #IceGrid.Node.Data=node_1 #21 #IceGrid.Node.CollocateRegistry=1 #22 #IceGrid.Node.Output=node_1 #23 #IceGrid.Node.RedirectErrToOut=1 #24 # 19 定义节点的名称,必须唯一 # 20 节点被访问的端口信息,注册服务使用这个端点和节点通信,通常设为default # 21 节点的数据目录的路径 # 22 定义节点是否和注册服务并置在一起,设为1时并置,设为0时不并置 # 23 节点标准输出信息重定向蹈的目录路径,会自动生成输出文件 # 24 节点上的服务程序的标准错误重定向到标准输出 # Traceproperties. # IceGrid.Node.Trace.Activator=1 #25 IceGrid.Node.Trace.Adapter=2 #26 IceGrid.Node.Trace.Server=3 #27 # 25 激活器跟踪级别,通常有0,1,2,3级,默认是0 # 26 对象适配器跟踪级别,通常有0,1,2,3级,默认是0 # 27 服务跟踪级别,通常有0,1,2,3级,默认是0 # # Dummy usernameand password for icegridadmin. # IceGridAdmin.Username=mygrid #28 IceGridAdmin.Password=mygrid #29 # 28 IceGrid管理器登录该应用的用户名 # 29 IceGrid管理器登录该应用的密码 从服务的config.slave: # # The IceGrid locator proxy. #主从注册表之间访问定位器配置 # Ice.Default.Locator=MCSLGrid/Locator:default -p 5061 #可指定ip #Ice.Default.Locator=MCSLGrid/Locator:default -h 192.168.1.102 -p 5061 # # The IceGrid instance name. # #IceGrid.InstanceName=MCSLGrid # # IceGrid registry configuration. # IceGrid.Registry.Client.Endpoints=default -p 15061 #可指定ip #IceGrid.Registry.Client.Endpoints=default -h 127.0.0.1 -p 15061 IceGrid.Registry.Server.Endpoints=default IceGrid.Registry.Internal.Endpoints=default #IceGrid.Registry.Data=db/LMDB_slave IceGrid.Registry.ReplicaName=Slave#指定从注册服务的名称 IceGrid.Registry.LMDB.Path=db/LMDB_slave # # IceGrid admin clients must use a secure connection to connect to the # registry or use Glacier2. # #IceGrid.Registry.AdminSessionManager.Endpoints=default IceGrid.Registry.PermissionsVerifier=MCSLGrid/NullPermissionsVerifier #7 IceGrid.Registry.AdminPermissionsVerifier=MCSLGrid/NullPermissionsVerifier #8 #IceGrid.Registry.SSLPermissionsVerifier=MCSLGrid/NullSSLPermissionsVerifier #9 #IceGrid.Registry.AdminSSLPermissionsVerifier=MCSLGrid/NullSSLPermissionsVerifier #10 # # IceGrid SQLconfiguration if using SQL database. # #Ice.Plugin.DB=IceGridSqlDB:createSqlDB #11 #IceGrid.SQL.DatabaseType=QSQLITE #12 #IceGrid.SQL.DatabaseName=register/Registry.db #13 # # #Ice Error andStandard output Set # #Ice.StdErr=slave_1/stderr.txt #14 #Ice.StdOut=slave_1/stdout.txt #15 # # Trace properties. # Ice.ProgramName=Slave IceGrid.Registry.Trace.Node=2 IceGrid.Registry.Trace.Replica=2 # # IceGrid nodeconfiguration. # #IceGrid.Node.Name=node_2 #19 #IceGrid.Node.Endpoints=default #20 #IceGrid.Node.Data=node_2 #21 #IceGrid.Node.CollocateRegistry=1 #22 #IceGrid.Node.Output=node_2 #23 #IceGrid.Node.RedirectErrToOut=1 #24 # Traceproperties. # IceGrid.Node.Trace.Activator=1 #25 #IceGrid.Node.Trace.Adapter=2 #26 #IceGrid.Node.Trace.Server=3 #27 # # Dummy usernameand password for icegridadmin. # IceGridAdmin.Username=mygrid #28 IceGridAdmin.Password=mygrid #29 serverMcs的配置config01.node(config02.node): # # The IceGrid locator proxy. # Ice.Default.Locator=MCSLGrid/Locator:default -p 5061:default -p 15061 #不是本地节点,需指定ip #Ice.Default.Locator=MCSLGrid/Locator:default -h 127.0.0.1 -p 5061:default -h 127.0.0.1 -p 15061 # # IceGrid node configuration. #"IceGrid.Node.Endpoints"的访问地址与"IceGrid.Registry.Internal.Endpoints=tcp -h localhost"一致 # IceGrid.Node.Name=Node21 IceGrid.Node.Endpoints=default #IceGrid.Node.Endpoints=default -h 127.0.0.1 IceGrid.Node.Data=db/node_21 IceGrid.Node.Output=db/node_out_21 #IceGrid.Node.RedirectErrToOut=1 #IceGrid.Node.Name = 172.16.14.165 //服务器地址 # # Trace properties. # Ice.ProgramName=Node IceGrid.Node.Trace.Replica=2 IceGrid.Node.Trace.Activator=1 #log tracing Ice.LogFile=iceserv.log Ice.LogFile.SizeMax=1048576 Ice.PrintStackTraces=2 #Ice.Trace.GC=1 Ice.Trace.Protocol=1 Ice.Trace.Slicing=1 Ice.Trace.Retry=2 Ice.Trace.Network=2 Ice.Trace.Locator=2 #warning Ice.Warn.Connections=1 Ice.Warn.Datagrams=1 Ice.Warn.Dispatch=1 Ice.Warn.AMICallback=1 #Ice.Warn.Leaks=1 serverDcs的config01.node(config02.node类似): # # The IceGrid locator proxy. # Ice.Default.Locator=MCSLGrid/Locator:default -p 5061:default -p 15061 #不是本地节点,需指定ip #Ice.Default.Locator=MCSLGrid/Locator:default -h 127.0.0.1 -p 5061:default -h 127.0.0.1 -p 15061 # # IceGrid node configuration. #"IceGrid.Node.Endpoints"的访问地址与"IceGrid.Registry.Internal.Endpoints=tcp -h localhost"一致 # IceGrid.Node.Name=Node11 IceGrid.Node.Endpoints=default #IceGrid.Node.Endpoints=default -h 127.0.0.1 IceGrid.Node.Data=db/node_11 IceGrid.Node.Output=db/node_out_11 #IceGrid.Node.RedirectErrToOut=1 #IceGrid.Node.Name = 172.16.14.165 //服务器地址 # # Trace properties. # Ice.ProgramName=Node IceGrid.Node.Trace.Replica=2 IceGrid.Node.Trace.Activator=1 #log tracing Ice.LogFile=iceserv.log Ice.LogFile.SizeMax=1048576 Ice.PrintStackTraces=2 #Ice.Trace.GC=1 Ice.Trace.Protocol=1 Ice.Trace.Slicing=1 Ice.Trace.Retry=2 Ice.Trace.Network=2 Ice.Trace.Locator=2 #warning Ice.Warn.Connections=1 Ice.Warn.Datagrams=1 Ice.Warn.Dispatch=1 Ice.Warn.AMICallback=1 #Ice.Warn.Leaks=1 配置完成后我们将配置启动脚本,有了本地配置的经验,我同样配置数个脚本,以win系统为例: (1)start_center_server.bat,用于启动主从中心服务 start /b /MIN "registry11" icegridregistry --Ice.Config=config.master start /b /MIN "registry12" icegridregistry --Ice.Config=config.slave (2)start_admin.bat,用于修改更新配置 ::如果更改配置,需要重新映射服务,删除数据目录并重新生成或更新,需先启动中心服务,再调用配置服务更新 ::start_center_server.bat icegridadmin --Ice.Config=config.admin -e "application add 'application.xml'" icegridadmin --Ice.Config=config.admin -e "application update 'application.xml'" (3)start_server.bat,启动节点服务集,本案例serverMcs和serverDcs有两个节点服务 cd D:\\SYE_MCS_PRO\\pcs_project\\MCS_server\\x64\\McsSrv start /b /MIN "node11" icegridnode --Ice.Config=config01.node start /b /MIN "node12" icegridnode --Ice.Config=config02.node cd D:\\SYE_MCS_PRO\\pcs_project\\DCS_server\\x64\\DcsSrv start /b /MIN "node21" icegridnode --Ice.Config=config01.node start /b /MIN "node22" icegridnode --Ice.Config=config02.node cd D:\\SYE_MCS_PRO\\pcs_project\\sye_mcs\\mgrs (4)stop_server.bat,关闭服务集使用 taskkill /f /im icegridregistry.exe taskkill /f /im icegridnode.exe taskkill /f /im glacier2router.exe taskkill /f /im MCS_server.exe taskkill /f /im DCS_server.exe 配置完成,先去配置一些服务需要的一些目录,以本地win服务为例, 如 D:\SYE_MCS_PRO\pcs_project\sye_mcs\mgrs\db\LMDB_master, D:\SYE_MCS_PRO\pcs_project\sye_mcs\mgrs\db\LMDB_slave, D:\SYE_MCS_PRO\pcs_project\MCS_server\x64\McsSrv\db\node_21, D:\SYE_MCS_PRO\pcs_project\MCS_server\x64\McsSrv\db\node_out_21, D:\SYE_MCS_PRO\pcs_project\DCS_server\x64\DcsSrv\db\node_12, D:\SYE_MCS_PRO\pcs_project\DCS_server\x64\DcsSrv\db\node_out_12 完成目录配置后 ,先start_center_server.bat服务,然后启动start_admin.bat(配置有改动时)和start_server.bat。 当服务启动稳定后,serverPcs服务应该是没有启动的,只有客户端连接需求后才会被触发启动。 serverPcs作为客户端与serverMcs通信,终端app与serverDcs通信,由于他们的注册主从服务一致,它们的ice配置文件config0.client如下: # # The IceGrid locator proxy. #"Ice.Default.Locator"的访问地址与"IceGrid.Registry.Client.Endpoints设置"一致 # Ice.Default.Locator=MCSLGrid/Locator:tcp -h localhost -p 5061:tcp -h localhost -p 15061 #Ice.Default.Locator=MCSLGrid/Locator:tcp -h www.syemcs.com -p 5061:tcp -h www.pytest.com -p 15061 #非本地连接,需指定IP #Ice.Default.Locator=MCSSVCGrid/Locator:tcp -h 192.168.1.102 -p 4061:tcp -h 192.168.1.102 -p 14061 #Ice.Default.Router=MCSSVCGlacier2/router:tcp -h www.syemcs.com -p 4064:ssl -h www.pytest.com -p 4065 现在启动测试样例,先启动本地服务集群的脚本(start_center_server.bat,start_admin.bat(配置有改动时),start_server.bat),再启动云端服务集群的脚本(start_center_server.bat,start_admin.bat(配置有改动时),start_server.bat),然后启动终端app测试,展示类似,只多了一级区域: ​​ 样例走通后,进行linux编译,然后部署在阿里云的ECS上,进行一些优化和调整,重新设计终端UI,撰写维护使用手册,开通给使用人员。嗯,现在每个被授权人可以通过外网通信实现对现场设备的实时监控。 可是项目还没有完结,领导又有新构想了,远程升级、日志备份云端和远程查阅、语音控制、视频发布等等,估计又要追加一堆微服务了。 嘿,没问题,就是能不能招人或找外包,或加点项目预算啥的。 项目开发还在路上,感觉坑越来越深了。

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

Keras搭建深度神经网络解决多分类问题

Keras介绍 Keras是一个开源的高层神经网络API,由纯Python编写而成,其后端可以基于Tensorflow、Theano、MXNet以及CNTK。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果。Keras适用的Python版本是:Python 2.7-3.6。 Keras,在希腊语中意为“角”(horn),于2015年3月份第一次发行,它可以在Windows, Linux, Mac等系统中运行。那么,既然有了TensorFlow(或Theano、MXNet、CNTK),为什么还需要Keras呢?这是因为,尽管我们可以用TensorFlow等来创建深度神经网络系统,但Tensorflow等使用相对低级的抽象,直接编写TensorFlow代码具有一定的挑战性,而Keras在TensorFlow的基础上

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

用函数计算搭建微服务——云客服访客名片

云客服可以方便快捷集成到用户的官网、APP、公众号等任意位置;依托阿里云智能算法,机器人能准确的理解用户的意图,并准确的回答用户的问题;提供完整的热线、在线服务功能,并能轻松连接企业的其他系统,如 CRM 等;动态管理客户和坐席使用的统一知识库、知识文章;实时汇总、实时分析服务中心的数据,帮助业务决策者从全局视角了解热门问题和当前的服务瓶颈;云客服是一套完整的智能服务体系。 访客名片是云客服上一个功能,用于关联云客服和客户 CRM 系统之间的用户,方便客服人员了解提问用户的基本信息,更好的支持用户。 目前云客服提供的访客名片集成指南是一个基于 Spring MVC 实现的 Web 项目,nodejs 语言背景的用户提出希望将 java 实现移植到函数计算服务,以服务的形式提供给 nodejs 实现的核心业务调用。 困难点 用户自己尝试过移

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

搭建Hadoop处理环境,零基础学习大数据

由于Hadoop需要运行在Linux环境中,而且是分布式的,因此个人学习只能装虚拟机,本文都以VMware Workstation为准,安装CentOS7,具体的安装此处不作过多介绍,只作需要用到的知识介绍。 VMware的安装,装好一个虚拟机后利用复制虚拟机的方式创建后面几个虚拟机,省时省力,需要注意的是需要修改每个虚拟机的IP与主机名。 所有虚拟机采用NAT模式上网,而且要保证与物理主机的IP互相能访问。 需要注意的几个问题。nat如果上网首先需要查看物理机(pc机)这个服务器已经启动。上网的原理:流量是走的物理网卡,但是它的ip,却是和物理机没有关系的。也就是说,无论你怎么更换网络环境,你的虚拟机都不需要做改变。这就是它的优点。 首先在安装VMware 之后,我们会看到多了两个网卡 这个如果经过网络配置的折磨,应该能找到着两个网卡:vmnet1和vmnet8,这里讲的是vmnet8。 重点看右侧第三图你会看到ip地址,这个ip地址,因个人而异,也就是说不同网络,不同环境,这个ip变化的概率是很大的。可能是192.168.0.1等等。这里也相当于我们编程的一个变量,这里是需要你根据你的环境来赋值的,建议vmnet1到vmnet8分别设置192.168.10.1到192.168.80.1,好作区分。 上面我们通过看到的虚拟机网卡的ip,为了避免混肴,上面的虚拟网卡和本地网络适配器处于同一界面。如下图: 而下面则是在打开虚拟机之后,通过菜单弹出 弹出之后,我们在看一下虚拟机的(交换机)vmnet8. 可以看到vmnet8子网ip和虚拟机网卡是出于同一个网段的。 同时在右侧net设置界面,我们可以看到网关为:192.168.106.2,改成192.168.80.2 虚拟机的设置会用到。 Linux基础知识 Linux的学习也是一个过程,因为可能你连最简单的开机和关机命令都不会,更不要谈配置网络。这里面给大家提供刚开始学习所查阅的资料和经验总结。 首先我们需要使用一些命令,进行网络配置,但是在网络配置中,这里面又必须懂得虚拟机的一些知识,所以前面的虚拟机知识需要掌握扎实一些。 在此注意CentOS7与CentOS6的命令有些不同,会一些常用命令是必备,每次开机或启动解压安装授权都是最基本的知识,其它的可以暂时不用学。 CentOS中安装java环境 下载对应32或64位jdk,设置好JDK环境变量PATH,具体的配置可自行Google。 环境准备 修改机器名,每个系统中都要修改成这样。 打开终端,切换到root用户下修改机器名称。 $ sudo su$ vim /etc/sysconfig/network在其中添加“HOSTNAME=H32” 添加每个服务器IP对应的机器名 三个ip地址都添加到各自的/etc/hosts文件中 每个系统中都要修改成这样 #编辑hostsvim /etc/hosts 关闭SELinux #编辑 SELinux 配置文件vim /etc/selinux/config#改状态SELINUX=disabled SSH设置 进入H30,查看ssh是否安装,如果有,继续,没有安装下。 rpm -qa|grep ssh 时间服务器安装 这里需要安装时间服务器,其他的服务器通过这个来进行多机器时间的同步,分布式部署时机器时间不一致会导致数据错误或组件内通讯错误。 安装httpd服务 httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。 安装yum-utils yum install yum-utils 用于在线yum安装 它是基於RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。(需要机器能访问外网) 准备资源和环境 下载Centos 7.2 的iso安装镜像,jdk1.8 for Linux压缩包,hadoop2.7.3压缩包(本来用hadoop3,发现后面不兼容hive的最新版本) Java基础知识 由于Hadoop框架源码都是以Java来写,因此最好都以Java作为开发的最佳语言,虽然说有些用C#做了封装,但性能已大打折扣。(这就是为什么说Java的学大数据有很大的优势,其它语言的还需要重新学习Java) Eclipse IDE使用 Linux和Windows下源码编译技术 还有最重要的是你的网速要好,因为安装过程中会下载依赖包,网不好会卡到你怀疑人生。 最后还需要有耐心,每台机子的环境都不一样,而且每个人下载的包的版本也有可能不一样 会导致各种问题,此时就需要耐心的去看日志,不停的尝试和仔细的对比安装步骤,可能就是少了个变量 或大小写错误或是要重启。 本文链接:http://bigdata.evget.com/post/2331.html

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

【最佳实践】如何搭建反向代理服务访问OSS资源?

1.当前存在的问题 无法通过固定的IP方式访问OSS:阿里云OSS通过Restful API方式对外提供服务。最终用户通过OSS默认域名或者绑定的自定义域名方式访问(例如:https://your_bucketname.oss-cn-hangzhou.aliyuncs.com/your_object ) 。您可以通过域名解析的方式获取某个Bucket域名对应的临时IP,但是由于阿里云OSS自身安全机制,Bucket域名对应的IP是会随机发生变化的。因此,您无法获取某个Bucket对应的长期有效IP地址。而某些企业由于安全机制,需要在出口防火墙配置策略,以限制内部员工和业务系统只能访问指定的公网IP。 互联网用户无法直接访问金融云OSS:由于金融云网络架构限制,金融云内网类型的Bucket只能在金融云内部访问。不支持在互联网上直接访问金

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

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

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册