├── Q#.md ├── TDD.md ├── 协议.md ├── Clojure.md ├── RESTFUL.md ├── 产品经理.md ├── 可行性分析技巧.md ├── CONTRIBUTING.md ├── DL.md ├── J.md ├── 公众联盟链.md ├── zabbix.md ├── Web3js.md ├── Distributed-System.md ├── blockchain.md ├── 项目管理.md ├── apidoc.md ├── golang.md ├── AI安全.md ├── 架构说明.md ├── EdgeComputing.md ├── 解决方案架构师.md ├── 产品运营.md ├── PM ├── IFTTT.md ├── 常用插件.md ├── git规范.md ├── jdk.md ├── .all-contributorsrc ├── Futurist.md ├── general_writing.md ├── docker-install.md ├── 一键部署脚本.md ├── CS_Step_By_Step.md ├── SmartContract.md ├── Web.md ├── 市场分析.md ├── README.md ├── IOT带来的飞轮效应.md ├── distributed_applications.md ├── Open_Project.md ├── immersion.md ├── 给初学者的区块链学习资料.md ├── FRP_EDA.md ├── docker.md ├── docker-mysql-install.md ├── fisco-bcos-resources.md ├── Shell.md ├── Complex_Event_Processing_and_Streaming_Data_Analytics.md ├── mysql.md ├── Middleware.md ├── 坐而论道_我也跟着说说FRP_FP.md ├── java.md ├── 讲讲FRP_FP.md ├── STOMP.md ├── grafana-influxdb-telegraf.md ├── Serverless.md └── 当我在看EDA时候.md /Q#.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /TDD.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /协议.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Clojure.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /RESTFUL.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /产品经理.md: -------------------------------------------------------------------------------- 1 | - 技能 2 | -------------------------------------------------------------------------------- /可行性分析技巧.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DL.md: -------------------------------------------------------------------------------- 1 | - deep learning 2 | - object detection 3 | 4 | -------------------------------------------------------------------------------- /J.md: -------------------------------------------------------------------------------- 1 | [diff](http://strictlypositive.org/diff.pdf) 2 | -------------------------------------------------------------------------------- /公众联盟链.md: -------------------------------------------------------------------------------- 1 | ### keyword 2 | - ccsci 3 | - 范畴 4 | - 治理模式 5 | - 行业边界 6 | 7 | 8 | -------------------------------------------------------------------------------- /zabbix.md: -------------------------------------------------------------------------------- 1 | [curlCallZabbixAPI](https://www.cnblogs.com/ruiy/p/curlCallZabbixAPI.html) 2 | -------------------------------------------------------------------------------- /Web3js.md: -------------------------------------------------------------------------------- 1 | ### web3js是使用注意事项 2 | #### 0x 3 | ``` 4 | 对入参以0x开始的字符串,会导致web3js出现异常 5 | ``` 6 | #### 解析返回值 7 | -------------------------------------------------------------------------------- /Distributed-System.md: -------------------------------------------------------------------------------- 1 | - [知识点](https://yq.aliyun.com/articles/719353?spm=a2c4e.11153959.0.0.58534977dxrNJu) 2 | -------------------------------------------------------------------------------- /blockchain.md: -------------------------------------------------------------------------------- 1 | ### 普及材料 2 | [精通比特币](http://v1.8btc.com/books/834/masterbitcoin2cn/_book/) 3 | 4 | ### paper 5 | -------------------------------------------------------------------------------- /项目管理.md: -------------------------------------------------------------------------------- 1 | ### 研发产品流程 2 | ![image](https://user-images.githubusercontent.com/6056769/166721130-0e0160b4-a87b-4371-946b-aac270f5c8cb.png) 3 | -------------------------------------------------------------------------------- /apidoc.md: -------------------------------------------------------------------------------- 1 | 目的:通过固定的格式,直接显示接口的API,简化写api文件的时间 2 | 3 | 1. 使用仓库是[apidoc](http://apidocjs.com/) 4 | 2. 建议直接上手使用example进行操作,否则会出现奇怪的bug 5 | 6 | [example](http://45.40.197.34/apidoc/#api-example-for-a-submenu-entry) 7 | -------------------------------------------------------------------------------- /golang.md: -------------------------------------------------------------------------------- 1 | ## 背景 2 | 3 | ## 1. 环境搭建 4 | - 修改环境变量 5 | - GOPATH 6 | 7 | ## 2. 语言特点 8 | 9 | ## 3. Step By Step 10 | - [example](https://gobyexample.com/) 11 | 12 | ## 4. 常用库 13 | 14 | ## 5. 需要注意的问题 15 | 16 | 17 | -------------------------------------------------------------------------------- /AI安全.md: -------------------------------------------------------------------------------- 1 | - [Is attacking machine learning easier than defending it?](http://www.cleverhans.io/security/privacy/ml/2017/02/15/why-attacking-machine-learning-is-easier-than-defending-it.html) 2 | - [从安全视角对机器学习的部分思考](https://mp.weixin.qq.com/s/kP4YuiksI1dfZdT8Z_j_cQ) 3 | -------------------------------------------------------------------------------- /架构说明.md: -------------------------------------------------------------------------------- 1 | 行业架构师和解决方案架构师 2 | 3 | - https://www.smartcity.team/consultingskills/experience/%E4%B8%9A%E5%8A%A1%E6%9E%B6%E6%9E%84%E6%98%AF%E4%BB%80%E4%B9%88/ 4 | - https://segmentfault.com/a/1190000040380632 5 | - https://www.cnblogs.com/WUXIAOCHANG/p/10968646.html 6 | -------------------------------------------------------------------------------- /EdgeComputing.md: -------------------------------------------------------------------------------- 1 | ## 边缘计算 2 | 边缘计算(Edge Computing) 3 | 4 | 随着物联网终端设备数量的迅速增加, 5 | 传统的基于云计算模型的集中式数据处理方式已不能有效处理网络边缘设备所产生的海量数据,存在网络阻塞、高延时、低服务质量等问题。 6 | 边缘计算中的”边缘”是个相对的概念,指从数据源到云计算中心数据路径之间的任意计算资源和网络资源。 7 | 8 | - 边缘计算所处的行业位置 9 | - [边缘计算的架构](https://arxiv.org/pdf/1702.05309.pdf) 10 | -------------------------------------------------------------------------------- /解决方案架构师.md: -------------------------------------------------------------------------------- 1 | 2 | 参考链接 3 | - https://www.cnblogs.com/x-knight/p/11443462.html 4 | - https://www.infoq.cn/article/rjzbaodznmjpudy3pyw1 5 | - https://developer.51cto.com/art/202109/681945.htm![image](https://user-images.githubusercontent.com/6056769/134740427-0094d541-ce03-4525-929f-a09e063d0666.png) 6 | -------------------------------------------------------------------------------- /产品运营.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ``` 4 | 产品研发期——产品上线前:首先产品运营要搞清楚产品的定位以及目标用户。 5 | 产品种子期——产品内测期:在这个阶段,产品运营主要目的在于收集用户行为数据和相关的问题反馈,和产品策划一起分析讨论进行产品优化。 6 | 产品成长期——产品爆发期:产品要爆发,活动策划是必不可少的一部分。 7 | 产品成熟期:稳定期对产品意义重大的就是小版本的迭代更新。产品运营就要做好产品策划和用户之间的桥梁作用。 8 | 产品衰退期:这个阶段,用户的流失加剧,用户活跃度也明显下滑,营收贡献也急剧下降。公司策略方面:技术的支持减少,新产品开始推出。 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /PM: -------------------------------------------------------------------------------- 1 | 卡诺模型(KANO模型)是对用户需求分类和优先排序的有用工具,以分析用户需求对用户满意的影响为基础,体现了产品性能和用户满意之间的非线性关系。 2 | 在卡诺模型中,将产品和服务的质量特性分为四种类型: 3 | - 魅力属性:用户意想不到的,如果不提供此需求,用户满意度不会降低,但当提供此需求,用户满意度会有很大提升; 4 | - 期望属性:当提供此需求,用户满意度会提升,当不提供此需求,用户满意度会降低; 5 | - 必备属性:当优化此需求,用户满意度不会提升,当不提供此需求,用户满意度会大幅降低; 6 | - 无差异因素:无论提供或不提供此需求,用户满意度都不会有改变,用户根本不在意; 7 | - 反向属性:用户根本都没有此需求,提供后用户满意度反而会下降 8 | -------------------------------------------------------------------------------- /IFTTT.md: -------------------------------------------------------------------------------- 1 | ### 什么是 IFTTT 2 | 3 | IFTTT ,是一个新生的网络服务平台,通过其他不同平台的条件来决定是否执行下一条命令。即对网络服务通过其他网络服务作出反应。IFTTT 得名为其口号“if this then that”。IFTTT的官方念法类似英语单词“gift”的“ift”,即不要发“g”的音。 4 | 5 | ### 实现原理 6 | 7 | IFTTT 基于任务的条件触发,类似编程语言,即:“若 XXX 进行 YYY 行为,执行 ZZZ。”。每一个可以触发或者作为任务的网站叫做一个 Channel,触发的条件叫做 Triggers,之后执行的任务叫做 Actions,综合上面的一套流程叫做 Task。 8 | 9 | ### 项目实践 10 | -------------------------------------------------------------------------------- /常用插件.md: -------------------------------------------------------------------------------- 1 | ###### 提供 GitHub 项目的树形视图,方便在线预览一个层级复杂的项目的文件结构 2 | - Octotree 3 | 4 | ###### 快速查询 5 | - listary 6 | 7 | 8 | ###### 模拟请求 9 | - postman 10 | 11 | ###### 工具栏控制 12 | - clover 13 | 14 | ###### 抓包工具 15 | - fiddler 16 | 17 | 18 | --- 19 | ###### apidoc 20 | - api生成 21 | 22 | ###### 日志和监控 23 | - grafana+influxDB+teleref 24 | - grafana+zabbix 25 | 26 | ###### ppt 27 | - nodejsSlide 直接使用Markdown 直接写ppt 28 | -------------------------------------------------------------------------------- /git规范.md: -------------------------------------------------------------------------------- 1 | ## git tag 2 | ### 轻量级标签 3 | 轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a,-s 或 -m 选项都不用,直接给出标签名字即可: 4 | 5 | ``` 6 | $ git tag v1.4-lw 7 | ``` 8 | 9 | ### 含附注的标签 10 | 11 | ``` 12 | $ git tag -a v1.4 -m 'my version 1.4' 13 | ``` 14 | 15 | ### 分享标签 16 | 默认情况下,git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可: 17 | 18 | ``` 19 | $ git push origin v1.5 20 | ``` 21 | 22 | ### release 参考 23 | [spring-boot](https://github.com/spring-projects/spring-boot/releases) 24 | -------------------------------------------------------------------------------- /jdk.md: -------------------------------------------------------------------------------- 1 | sudo tar xzf ~/Downloads/jdk-8u101-linux-x64.tar.gz 2 | mv jdk... /usr/local/jdk 3 | 4 | 5 | vim /etc/profile 6 | 7 | JAVA_HOME=/usr/local/jdk 8 | CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar 9 | PATH=$JAVA_HOME/bin:$HOME/bin:$HOME/.local/bin:$PATH 10 | export JAVA_HOME CLASSPATH PATH 11 | 12 | vim ~/.bashrc 13 | 14 | source /etc/profile 15 | 16 | JAVA_HOME=/usr/local/jdk 17 | CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar 18 | PATH=$JAVA_HOME/bin:$HOME/bin:$HOME/.local/bin:$PATH 19 | export JAVA_HOME CLASSPATH PATH 20 | 21 | source ~/.bashrc 22 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "CONTRIBUTING.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "cristicmf", 10 | "name": "cristicmf", 11 | "avatar_url": "https://avatars0.githubusercontent.com/u/30070842?v=4", 12 | "profile": "https://github.com/cristicmf", 13 | "contributions": [ 14 | "maintenance" 15 | ] 16 | }, 17 | 18 | ], 19 | "contributorsPerLine": 6, 20 | "projectName": "WeEvent", 21 | "projectOwner": "cristicmf", 22 | "repoType": "github", 23 | "repoHost": "https://github.com", 24 | "skipCi": true 25 | } 26 | -------------------------------------------------------------------------------- /Futurist.md: -------------------------------------------------------------------------------- 1 | someone 2 | 3 | [David Furlonger](https://www.gartner.com/analyst/14043/David-Furlonger) 4 | 5 | something 6 | 7 | How Will Blockchain Affect Your Business Model? (Barcelona, Spain) 8 | Use Business Models to Define Your Digital Transformation (Sao Paulo, Brazil) 9 | 10 | Key Trends in AI Applications (Orlando, Florida) 11 | A Framework for Applying AI in the Enterprise (Orlando, FL) 12 | 13 | --- 14 | Gossip 15 | 16 | Security is handled by cryptographic protocols and techniques that ensure the permanence, resilience and immutability of the data. 17 | 18 | Additionally, much of what is on the market as an enterprise “blockchain” solution lacks at least two of the five core components: Encryption, immutability, distribution, decentralization and tokenization. 19 | 20 | [the-cios-guide-to-quantum-computing](https://www.gartner.com/smarterwithgartner/the-cios-guide-to-quantum-computing/) 21 | 22 | 23 | --- 24 | 咨询 25 | [nri](https://www.nri.com/en/knowledge/publication/fis/lakyara/lst/2018/04/01) 26 | -------------------------------------------------------------------------------- /general_writing.md: -------------------------------------------------------------------------------- 1 | ## how to start general writing 2 | 3 | - [https://owl.purdue.edu/owl/general_writing/index.html](https://owl.purdue.edu/owl/general_writing/index.html) 4 | - [https://writing.ku.edu/abstract](https://writing.ku.edu/abstract) 5 | - [https://owl.purdue.edu/owl/general_writing/index.html](https://owl.purdue.edu/owl/general_writing/index.html) 6 | - [coloradocollege.edu/offices/colketcenter/writing-center/resources/forstudents/](coloradocollege.edu/offices/colketcenter/writing-center/resources/forstudents/) 7 | - [http://lss.info.yorku.ca/files/2013/08/PQ3R-Handout.pdf](http://lss.info.yorku.ca/files/2013/08/PQ3R-Handout.pdf) 8 | - [http://guidetogrammar.org/grammar/composition/brainstorm_clustering.htm](http://guidetogrammar.org/grammar/composition/brainstorm_clustering.htm) 9 | - [https://writingcenter.unc.edu/tips-and-tools/understanding-assignments/](https://writingcenter.unc.edu/tips-and-tools/understanding-assignments/) 10 | - [http://writing2.richmond.edu/writing/wweb/structure.html](http://writing2.richmond.edu/writing/wweb/structure.html) 11 | - [https://www.thoughtco.com/the-introductory-paragraph-1857260](https://www.thoughtco.com/the-introductory-paragraph-1857260) 12 | - [https://writingcenter.fas.harvard.edu/pages/ending-essay-conclusions](https://writingcenter.fas.harvard.edu/pages/ending-essay-conclusions) 13 | - [https://www.hamilton.edu/academics/centers/writing/writing-resources](https://www.hamilton.edu/academics/centers/writing/writing-resources) 14 | -------------------------------------------------------------------------------- /docker-install.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 安装 Docker 4 | 5 | 1、卸载老版本: 6 | ``` 7 | #清理docker 8 | $ yum remove docker \ 9 | docker-client \ 10 | docker-client-latest \ 11 | docker-common \ 12 | docker-latest \ 13 | docker-latest-logrotate \ 14 | docker-logrotate \ 15 | docker-selinux \ 16 | docker-engine-selinux \ 17 | docker-engine 18 | 19 | $ rm -rf /usr/lib/systemd/system/docker.service.d \ 20 | /home/lib/docker \ 21 | /var/run/docker 22 | 23 | #清理flanneld 24 | $ rm -rf /usr/lib/systemd/system/flanneld.service \ 25 | /usr/bin/flanneld \ 26 | /etc/sysconfig/flanneld 27 | 28 | #清理kube* 29 | $ rm -rf /usr/lib/systemd/system/kube* \ 30 | /etc/sysconfig/kube* \ 31 | /usr/bin/kube* \ 32 | /usr/local/bin/kube* \ 33 | /var/lib/kubelet 34 | ``` 35 | 36 | 2、安装新版本: 37 | ``` 38 | $ yum install -y container-selinux-2.74-1.el7.noarch.rpm 39 | $ yum install -y pigz-2.3.3-1.el7.centos.x86_64.rpm 40 | $ yum install -y containerd.io-1.2.0-3.el7.x86_64.rpm 41 | $ yum install -y docker-ce-cli-18.09.0-3.el7.x86_64.rpm 42 | $ yum install -y docker-ce-18.09.0-3.el7.x86_64.rpm 43 | ``` 44 | 45 | 3、配置 46 | ``` 47 | $ vi /usr/lib/systemd/system/docker.service 48 | 49 | # 修改前 50 | ExecStart=/usr/bin/dockerd -H unix:// 51 | 52 | # 修改后 53 | EnvironmentFile=-/run/flannel/docker 54 | ExecStart=/usr/bin/dockerd --selinux-enabled --graph=/home/lib/docker -H unix:// $DOCKER_NETWORK_OPTIONS 55 | ``` 56 | 57 | 4、启动docker服务并查看docker版本 58 | ``` 59 | $ systemctl enable docker && systemctl daemon-reload 60 | $ systemctl start docker 61 | 62 | 63 | $ docker -v 64 | Docker version 18.09.0, build 4d60db4 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /一键部署脚本.md: -------------------------------------------------------------------------------- 1 | ### 脚本要点 2 | ##### shell 脚本: 3 | ``` 4 | wget,tar,zip, 5 | cd,ls,rm,cp,mkdir 6 | echo,sed,ps,netstat 7 | grep,awk,,wc,head,tail,exit 8 | ``` 9 | 10 | ##### 1. 参数的输入 11 | 明确入参 12 | 13 | ##### 2. 用法检查 14 | 15 | 检测用户的入参数,提示用户怎么用,比如说 ./install.sh -P /data/root/test 16 | 脚本说明: 17 | ``` 18 | if [ $# -lt 2 ]; then 19 | echo "Usage:" 20 | echo " ./install.sh -P /data/root/test" 21 | exit 1 22 | fi 23 | 24 | ``` 25 | 26 | ##### 3. 读取配置文件,获取参数 27 | 28 | 读取配置文件,解析配置文件的参数,检查配置是否合理 29 | 假设使用的配置是`test.ini` 30 | ``` 31 | $ cat test.ini 32 | [mysql] 33 | ip=127.0.0.1 34 | port=3306 35 | ``` 36 | 37 | - 读取配置文件和参数 38 | ``` 39 | value=$(crudini --get $file $section $param) 40 | mysql_ip=$($value "mysql" "ip") 41 | ``` 42 | 通过上面可以获取mysql_ip 43 | 44 | - 检查配置 45 | 46 | ``` 47 | function checkIp(){ 48 | if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 49 | exit 0 50 | else 51 | echo "fail" 52 | exit 1 53 | fi 54 | } 55 | 56 | function checkPort(){ 57 | local port="$1" 58 | local -i port_num=$(to_int "${port}" 2>/dev/null) 59 | 60 | if (( $port_num < 1 || $port_num > 65535 )) ; then 61 | echo "*** ${port} is not a valid port" 1>&2 62 | exit 1 63 | fi 64 | } 65 | ``` 66 | ##### 4. 拼接参数和安装模块 67 | - 如果有不同模块安装,用户需要进行并且参数,并安装其他的模块。 68 | 69 | ##### 5. 编写启动脚本、停止脚本 70 | - 启动服务脚本 71 | - 停止服务脚本 72 | - 监控脚本 73 | ##### 6. 编写监控脚本 74 | 75 | 通过crontab,进行服务的拉起 76 | ##### 7. 检查服务脚本 77 | 编写curl 脚本,查看服务是否正常 78 | 79 | ##### 8. 其他 80 | - 统一处理控制台输屏 81 | 82 | ##### 9. 初始化系统 83 | - 如果有mysql,导入数据库结构和数据 84 | 85 | ##### 10. 检查服务 86 | - 检查关键业务是否正常 87 | -------------------------------------------------------------------------------- /CS_Step_By_Step.md: -------------------------------------------------------------------------------- 1 | ### 入门 2 | 3 | #### 1.1 语言 4 | - python 5 | - Java编程思想 (第4版)https://book.douban.com/subject/2130190/ 6 | - Effective Java: Second Edition https://book.douban.com/subject/2696119/ 7 | - 面向对象 https://book.douban.com/subject/3530721/ 8 | 9 | #### 1.2 数据库 10 | - 数据库系统概念 https://book.douban.com/subject/10548379/ 11 | 12 | #### 1.3 算法&数据结构 13 | - 书籍 https://book.douban.com/subject/20432061/ 14 | - 在线视频 https://www.bilibili.com/video/av75424673 15 | - 《数据结构》 16 | 17 | 18 | #### 1.4 Linux 19 | - 鸟哥的Linux私房菜:书籍 http://cn.linux.vbird.org/linux_basic/linux_basic.php 20 | 21 | #### 1.5 计算机网络 22 | - 《图解Http》 23 | - 《HTTP详解》 24 | - 计算机网络 https://book.douban.com/subject/30280001/ 25 | - 《TCP/IP详解》 26 | 27 | #### 1.6 计算机系统 28 | - 《深入理解计算机系统》 29 | - 《操作系统》 30 | 31 | #### 1.7 汇编语言 32 | 33 | #### 1.8 软件工程 34 | - 参考书籍 https://book.douban.com/subject/6047742/ 35 | 36 | #### 1.9 设计模式 37 | - 参考书籍 https://book.douban.com/subject/2243615/ 38 | 39 | #### 1.10 运维 40 | - 监控 41 | - 自动集成 42 | - 容器:Docker 43 | - 自动化测试 44 | 45 | #### 1.11 中间件 46 | - mWeb Server:Nginx,Tomcat 47 | - 缓存:本地缓存、客户端缓存、服务端缓存 48 | - 消息队列 49 | - 日志系统 50 | - 定时调度 51 | - API网关 52 | - 配置中心 53 | 54 | #### 1.12 项目管理 55 | - 架构评审 56 | - 重构 57 | - 代码规划 (google style) 58 | - 代码Review 59 | - 编程模式(敏捷开发) 60 | 61 | ### 进阶 62 | #### 2.1 分布式 63 | - 扩展性 64 | - 稳定性&&高可用 65 | - 数据扩展 66 | - 服务治理 67 | - 分布式一致性 68 | - 幂等 69 | 70 | #### 2.2 分布式文档 71 | 72 | #### 2.3 书籍推荐 73 | - 计算机程序的构造和解释(SICP) https://book.douban.com/subject/1148282/ 74 | - 分布式系统 https://book.douban.com/subject/6047742/ 75 | 76 | #### 2.4 安全 77 | 78 | #### 2.5 大数据 79 | 80 | #### 2.6 常用工具 81 | 82 | #### 2.7 开源 83 | 84 | 85 | -------------------------------------------------------------------------------- /SmartContract.md: -------------------------------------------------------------------------------- 1 | ## 1. 编写合约常见问题和注意事项 2 | ### 1.1 mapping的使用 3 | - 大量的使用mapping,导致性能变差 4 | 5 | ### 1.2 调用合约注意事项 6 | 7 | - 合约调用合约,不能使用不定长字符串作为参数 8 | ``` 9 | string 是不可以,bytes32 可以 10 | ``` 11 | 12 | - memory 定义的内存字段 13 | ``` 14 | 1.不能超过16个 15 | 2.一般使用数组进行存储 16 | 3. 合约之间调用,参数传递,不能使用String类型 17 | 4. 合约查找数据时,减少遍历,可以使用mapping替代 18 | ``` 19 | 20 | ### 1.3 合约写日志 21 | 22 | - 在合约代码中 23 | ```solidity 24 | contract SimpleDemo { 25 | int256 storedData; 26 | event AddMsg(address indexed sender, bytes32 msg); 27 | ... 28 | 29 | function setData(int256 x) public{ 30 | storedData = x; 31 | AddMsg(msg.sender, "[in the set method]"); 32 | } 33 | ... 34 | } 35 | 36 | ``` 37 | 38 | - 在脚本 39 | 40 | ```javascript 41 | var event = instance.AddMsg({}, function(error, result) { 42 | if (!error) { 43 | var msg = "AddMsg: " + utils.hex2a(result.args.msg) + " from " 44 | console.log(msg); 45 | return; 46 | } else { 47 | console.log('it error') 48 | } 49 | }); 50 | 51 | function hex2a(hex) { 52 | var str = ''; 53 | for (var i = 0; i < hex.length; i += 2) { 54 | var v = parseInt(hex.substr(i, 2), 16); 55 | if (v) str += String.fromCharCode(v); 56 | } 57 | return str; 58 | } 59 | ``` 60 | 61 | ## 2. 合约灰度部署策略 62 | - [合约灰度部署](https://gist.github.com/cristicmf/b48e309763e39a5a531cc7513c56f164) 63 | 64 | ## 3. 学习资料 65 | - [smart-contract-best-practices](https://github.com/ConsenSys/smart-contract-best-practices) 66 | - [solidity](http://solidity.readthedocs.io/en/latest/security-considerations.html) 67 | - [truffle development framework](https://github.com/trufflesuite/truffle) 68 | 69 | ## 4. 智能合约架构设计 70 | 71 | ##### somethings 72 | - [smart-contracts-and-bitcoin](https://medium.com/@maraoz/smart-contracts-and-bitcoin-a5d61011d9b1) 73 | -------------------------------------------------------------------------------- /Web.md: -------------------------------------------------------------------------------- 1 | 2 | # 前端学习 3 | ## 踩过的坑 4 | ### 1. Provisional headers are shown 5 | 6 | 场景:打开一个页面,发送一个请求,出现`Provisional headers are shown` 7 | 8 | 查找问题,定位过程: 9 | 1. 点击打开 `chrome://net-internals` 10 | ``` 11 | Net Internals 是一套工具集合,用于帮助诊断网络请求与访问方面的问题,它通过监听和搜集 DNS,Sockets,SPDY,Caches 等事件与数据来向开发者反馈各种网络请求的过程、状态以及可能产生影响的因素。 12 | ``` 13 | 2. 在开始的页面触发请求 14 | 3. 在`chrome://net-internals`的event 里面查找,刚刚触发的请求,可以通过关键词查询。可以看到相关`invalid`的信息就可以定位问题。 15 | 16 | 复现问题:将后端设置成`https`,前端请求并非是`https`的情况,就可以触发这个问题。 17 | 18 | 19 | 20 | `provisional headers are shown`出现的情况 21 | 22 | ``` 23 | 跨域,请求被浏览器拦截 24 | 请求被浏览器插件拦截 25 | 服务器出错或者超时,没有真正的返回 26 | 强缓存from disk cache或者from memory cache,此时也不会显示 27 | ``` 28 | ### 2. HTML5页面调起APP 29 | - [HTML5页面调起APP](https://segmentfault.com/a/1190000009496897) 30 | - [可以参考的库](https://github.com/cristicmf/html-page-call-native) 31 | 32 | 33 | --- 34 | 35 | ## 前端基础 36 | - 事件冒泡 37 | - this 38 | - 作用域 39 | - 闭包 40 | - bind call apply 41 | - clone 42 | - 科里化 43 | 44 | ### 安全 45 | - XSS原理、场景 46 | 47 | ### 劫持 48 | - 浏览劫持 49 | - CDN劫持 50 | 51 | ### 缓存 52 | - CDN 缓存 53 | - 浏览器缓存 54 | 55 | ### 计算机网络 56 | - 204 304 101 206 502 57 | - https 58 | - http2.0 http1.0 http1.1 59 | 60 | ### 跨域 61 | - 同源策略 62 | - cors 63 | - jsonp 64 | - iframe 65 | - img 66 | 67 | ### 前端框架 68 | - vuejs 69 | - react 70 | - zeptojs 71 | 72 | ## 数据上报、分析以及服务监控 73 | - 安全监控 sentry 74 | - onerror try...catch 75 | - 重写console,进行错误分析 76 | 77 | ## 调试技巧 78 | - 重写console 79 | - fidller + willow + Rosin,快速调试移动端 80 | 81 | ## 算法和数据结构 82 | - 快排序 83 | - 动态规划 84 | - 贪心算法 85 | - [算法导论视频](http://open.163.com/special/opencourse/algorithms.html) 86 | 87 | ## 设计模式 88 | 89 | ## nodejs 90 | ### nodejs基础 91 | - 异步 92 | - 协程 93 | - promise 94 | - fetch 95 | - io多路复用 epoll 96 | 97 | ### nodejs直出 98 | - 使用nodejs+vue+vuex直出,应用于 99 | 100 | ## 有意思的问题 101 | - 当“当浏览器输入一行url”我想到了什么 102 | 103 | ## 编程思想 104 | ### 函数式编程 105 | 106 | ## 其他 107 | - nginx 108 | - redis 109 | 110 | ## 书籍【推荐】 111 | - javascript高级编程 112 | - 你不知道的javascript 113 | - http权威指南 114 | - 高性能mysql 115 | - 操作系统 116 | - 算法导论  117 | - SICP 118 | -------------------------------------------------------------------------------- /市场分析.md: -------------------------------------------------------------------------------- 1 | ## 分析策略 2 | 3 | ### SWOT分析模型 4 |  在现在的战略规划报告里,SWOT分析应该算是一个众所周知的工具。来自于麦肯锡咨询公司的SWOT分析,包括分析企业的优势(Strengths)、劣势(Weaknesses)、机会(Opportunities)和威胁(Threats)。因此,SWOT分析实际上是将对企业内外部条件各方面内容进行综合和概括,进而分析组织的优劣势、面临的机会和威胁的一种方法。 5 | 6 |   通过SWOT分析,可以帮助企业把资源和行动聚集在自己的强项和有最多机会的地方;并让企业的战略变得明朗。 7 | 8 | ### MECE法 9 | MECE,是Mutually Exclusive Collectively Exhaustive,中文意思是“相互独立,完全穷尽”。 也就是对于一个重大的议题,能够做到不重叠、不遗漏的分类,而且能够借此有效把握问题的核心,并解决问题的方法。 10 | 11 |   它是麦肯锡的第一个女咨询顾问巴巴拉·明托(Barbara Minto)在金字塔原理(The Minto Pyramid Principle)中提出的一个很重要的原则。 12 | 13 |   所谓的不遗漏、不重叠指在将某个整体(不论是客观存在的还是概念性的整体)划分为不同的部分时,必须保证划分后的各部门符合以下要求: 14 | 15 | 各部分之间相互独立 (Mutually Exclusive) 16 | 所有部分完全穷尽 (Collectively Exhaustive) 17 |   MECE(相互独立、完全穷尽)是麦肯锡思维过程的一条基本准则。 “相互独立”意味着问题的细分是在同一维度上并有明确区分、不可重迭的,“完全穷尽” 则意味着全面、周密。 18 | 19 |   该方案重点在于帮助分析人员找到所有影响预期效益或目标的关键因素,并找到所有可能的解决办法,而且它会有助于管理者进行问题或解决方案的排序、分析,并从中找到令人满意的解决方案。通常的做法分两种: 20 | 21 |   一是在确立问题的时候,通过类似鱼刺图的方法,在确立主要问题的基础上,再逐个往下层层分解,直至所有的疑问都找到,通过问题的层层分解,可以分析出关键问题和初步的解决问题的思路; 22 | 23 |   另一种方法是结合头脑风暴法找到主要问题,然后在不考虑现有资源的限制基础上,考虑解决该问题的所有可能方法,在这个过程中,要特别注意多种方法的结合有可能是个新的解决方法,然后再往下分析,每种解决方法所需要的各种资源,并通过分析比较,从上述多种方案中找到目前状况下最现实最令人满意的答案。 24 | 25 | 26 | 27 | ### PPP模式 28 | 29 | PPP模式即Public—Private—Partnership的字母缩写,通常译为“公共私营合作制”,是指政府与私人组织之间,为了合作建设城市基础设施项目。或是为了提供某种公共物品和服务, 以特许权协议为基础,彼此之间形成一种伙伴式的合作关系,并通过签署合同来明确双方的权利和义务,以确保合作的顺利完成,最终使合作各方达到比预期单独行动更为有利的结果。 30 | 31 | ### 波特五力分析模型 32 | 五力分析模型是迈克尔·波特(Michael Porter)于80年代初提出,对企业战略制定产生全球性的深远影响。用于竞争战略的分析,可以有效的分析客户的竞争环境。五力分别是: 供应商的议价能力、购买者的议价能力、潜在竞争者进入的能力、替代品的替代能力、行业内竞争者现在的竞争能力。五种力量的不同组合变化 最终影响行业利润潜力变化。 33 | 34 | 35 | ### 巴纳姆效应 36 | 37 | 38 | 一位名叫肖曼·巴纳姆的著名魔术师在评价自己的表演时说,他之所以很受欢迎是因为节目中包含了每个人都喜欢的成分,所以他使得"每一分钟都有人上当受骗"。 39 | 人们常常认为一种笼统的、一般性的人格描述十分准确地揭示了自己的特点,心理学上将这种倾向称为"巴纳姆效应"。 40 | 41 | 42 | 43 | ### 狄德罗效应又称配套效应 44 | 狄德罗效应,是由18世纪法国有个哲学家叫丹尼斯·狄德罗发现。狄德罗效应是一种常见的“愈得愈不足效应”,在没有得到某种东西时,心里很平稳,而一旦得到了,却不满足。 45 | 46 | 狄德罗效应给人们一种启示:对于那些非必需的东西尽量不要。因为如果你接受了一件,那么外界的和心理的压力会使你不断地接受更多非必需的东西。 47 | 48 |   1.相信我可以配得上华贵的袍子 49 | 50 |   在这里,我们把“狄德罗的袍子”看做是更高更好的追求。人们在树立了远大理想抱负的时候,就会逼着自己摆脱落后的现状,去积极追求更好的生活。那些之所以成功的人,正是坚信自己一定能摆脱贫穷命运,正是因为他们有勇气相信自己是穿华贵袍子的人,是值得享受更美好生活的人,勇于去追求和创造,才拥有了今天我们看到的更美好的生活。然而并不是所有人都有勇气,大多数人一辈子甘于披着贫穷的外衣,告诉自己,这就是命运。 51 | 52 |   2. 从一点一滴做起,逐步完善目标 53 | 54 |   缺乏自信心的人往往会说:“你看,我什么都做不好,我没有任何优点,我一事无成。”可是谁是一蹴而就的呢?灰心丧气的时候想一想孩童的牙牙学语、蹒·学步,成功的经验都是一步一个脚印,从一点一滴积攒起来的。先有了“袍子”,再换“沙发”、“地毯”,最后换“房子”,为自己建立一个逐步上升的目标等级。美好的生活就这样逐步地实现了。 55 | 56 | 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 🍕 CCSCI 2 | - [区块链技术智能合约入门](https://github.com/cristicmf/bcos-qucik-start-demo/blob/master/README.md) 3 | - [FISCO-BCOS学习资料](https://github.com/cristicmf/hackathon/blob/master/FISCO-BCOS-Resources.md) 4 | - [给初学者的区块链学习资料](https://github.com/cristicmf/curious-cat/blob/master/%E7%BB%99%E5%88%9D%E5%AD%A6%E8%80%85%E7%9A%84%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99.md) 5 | - [量子计算](https://github.com/cristicmf/Q-learn) 6 | - [EdgeComputing](https://github.com/cristicmf/curious-cat/blob/master/EdgeComputing.md) 7 | 8 | ### 上义文 9 | - 🥗[当我在看EDA时候,我想到了什么](https://github.com/cristicmf/curious-cat/blob/master/%E5%BD%93%E6%88%91%E5%9C%A8%E7%9C%8BEDA%E6%97%B6%E5%80%99.md) 10 | - 🥝[hey_FRP](https://github.com/cristicmf/curious-cat/blob/master/%E8%AE%B2%E8%AE%B2FRP_FP.md) 11 | - 🍕[FRP_EDA](https://github.com/cristicmf/curious-cat/blob/master/FRP_EDA.md) 12 | - 🥝[分布式系统](https://github.com/cristicmf/curious-cat/blob/master/distributed_applications.md) 13 | - 🍕[中间件分析](https://github.com/cristicmf/curious-cat/blob/master/Middleware.md) 14 | 15 | ### 项目管理 16 | - [研发产品流程梳理](https://github.com/cristicmf/curious-cat/blob/master/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86.md) 17 | 18 | 19 | ### 开源项目 20 | - [开源项目](https://github.com/cristicmf/curious-cat/blob/master/Open_Project.md) 21 | 22 | 23 | ### 微服务 24 | - DDD 25 | 26 | 27 | ### 协议 28 | - [STOMP](https://github.com/cristicmf/stompjs) 29 | - MQTT 30 | 31 | 32 | ### 工具 33 | - [grafana-influxdb-telegraf](https://github.com/cristicmf/curious-cat/blob/master/grafana-influxdb-telegraf.md) 34 | - [docker安装](https://github.com/cristicmf/curious-cat/blob/master/docker-install.md) 35 | - [docker 安装 mysql](https://github.com/cristicmf/curious-cat/blob/master/docker-mysql-install.md) 36 | 37 | ### 常用工具和技巧 38 | 39 | - [前端基础](https://github.com/cristicmf/knitmesh/blob/master/Web.md) 40 | - [常用插件](https://github.com/cristicmf/curious-cat/blob/master/%E5%B8%B8%E7%94%A8%E6%8F%92%E4%BB%B6.md) 41 | 42 | 43 | --- 44 | ### 常用shell脚本 45 | - [一键部署服务脚本](https://github.com/cristicmf/curious-cat/blob/master/%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2%E8%84%9A%E6%9C%AC.md) 46 | - [Shell 常用命令](https://github.com/cristicmf/knitmesh/blob/master/Shell.md) 47 | - [mysql常用命令](https://github.com/cristicmf/curious-cat/blob/master/mysql.md) 48 | 49 | --- 50 | ### SKILL 51 | - [immersion learner](https://github.com/cristicmf/curious-cat/blob/master/immersion.md) 52 | -------------------------------------------------------------------------------- /IOT带来的飞轮效应.md: -------------------------------------------------------------------------------- 1 | 齿轮效应:一家公司核心业务模块之间的互相推动就像咬合的齿轮,从静止到转动要花费很大力气,一旦高速转动后,使其停下来就需要克服很大的阻力。 2 | 3 | IOT的齿轮效应,促进了行业的数字化转型、区块链、人工智能(AI)、5G的发展 4 | 5 | ## 1. 区块链和物联网结合 6 | 7 | BCG:研究表明,在区块链与物联网的结合应用方面,汽车和消费品行业处于领先地位,其次是医疗、科技和电信、工业品等行业。应用案例中,有近三分之一适用于多个行业,其余则适用于某个特定行业。 8 | 9 | 10 | 11 | ****物联网解决新型生产力的问题,区块链解决新型生产关系的问题,它通过经济的正向和反向激励,实现了人与人之间前所未有的强协作,从而推动生产关系的革新。 12 | 13 | ## 2. IIOT+5G 14 | 工业物联网(IIoT)是一个快速发展的行业,占全球物联网支出的最大份额。据IDC和SAP称,2017年,全球60%的制造商使用连网设备产生的数据来分析流程并确定决策。 15 | 16 | ### 行业: 17 | #### 1、数字/连网工厂 18 | 支持物联网的机器可以向制造商等合作伙伴或现场工程师传输操作信息,这将使运营管理人员和工厂负责人能够远程管理工厂单元并利用流程自动化和优化。与此同时,数字连接单元将建立更好的命令行,并帮助确定管理者的关键结果区域(KRA)。 19 | #### 2、设施管理 20 | 在制造装备中使用物联网传感器可实现基于状态的维护警报。有许多关键机床需要在特定温度和振动范围内运行,物联网传感器可以主动监控机器并在设备偏离其规定参数时发出警报。通过确保机器的规定工作环境,制造商可以节约能源、降低成本、消除机器停机时间并提高运营效率。 21 | #### 3、生产流程监控 22 | 制造流程中的物联网可以实现从精炼过程到最终产品包装的全面生产线监控。这种对流程(近乎)实时的全面监控提供了建议操作调整的范围,以便更好地管理运营成本。此外,密切监控可以识别生产滞后,并消除了废物和不必要的制品库存。 23 | #### 4、库存管理 24 | 物联网应用允许监控整个供应链中的所有事件。使用这些系统,可在项目层级上全局跟踪和跟踪库存,并通知用户任何与项目有关的重大偏差。这提供了库存的跨渠道可见性,并向管理人员提供对可用材料、制品和新材料到达时间的实际估计。最终,这优化了供应,降低了价值链中的共享成本。 25 | #### 5、工厂安全和保障 26 | 物联网结合大数据分析可以提高工厂员工的整体安全保障系数。通过监控健康和安全的关键绩效指标,例如受伤和疾病发生率、未遂事件、偶尔和长期缺勤、车辆事故以及日常运营中的财产损坏或丢失。因此,有效监控确保了更好的安全性,滞后指标(如果有的话)可以得到解决,从而确保健康、安全和环境( HSE )问题得到适当的补救。 27 | #### 6、质量控制 28 | 物联网传感器从产品周期的各个阶段收集汇总产品数据和其他第三方数据。该数据涉及所用原料的组成、温度和工作环境、废物、运输等对最终产品的影响。此外,如果在最终产品中使用,物联网设备可以提供有关客户的产品使用体验数据,所有这些客户的使用数据稍后都可以进行分析,以识别和纠正产品质量问题。 29 | #### 7、包装优化 30 | 通过在产品和/或包装中使用物联网传感器,制造商可以从多个客户那里了解产品的使用模式和处理方式。智能跟踪机制还可以跟踪运输过程中的产品劣化以及天气、道路和其他环境变量对产品的影响。这将提供可用于重新设计产品和包装的见解,以便在客户体验和包装成本方面获得更好的表现。 31 | #### 8、物流和供应链优化 32 | 工业物联网( IIoT )可以通过跟踪材料、设备和产品在供应链中的移动,来提供对实时供应链信息的访问。有效的报告使制造商能够收集交付信息并将其输入ERP、PLM和其他系统。通过将工厂与供应商连接起来,与供应链相关的所有各方都可以追踪相互依赖性、材料流动和制造周期时间。这些数据将有助于制造商预测问题,减少库存和资本需求。 33 | 34 | 公司: 35 | Augury公司 36 | 37 | ##### 技术Feature: 38 | 1. 边缘计算 39 | 40 | 边缘计算是一种基础技术架构,可以在生产设施(设备)中现场收集、分析和存储数据,从而节省时间并帮助维护运营,而不是依赖于将所有数据存储在云中的较慢系统。边缘计算已经对维持正常运行和提供接近实时的数据和分析产生了重大影响,以优化工业物联网的性能和工业自动化的未来。 41 | 42 | 2. 雾计算 43 | 44 | 雾计算是一种更接近边缘的云计算形式,因此它可以处理大量数据,而无需将数据推送到云中。通过处理边缘和数据中心云之间的实时物联网请求,雾计算将提高边缘的能力。虽然这些预期的好处使雾计算对于希望使用工业物联网扩展其网络的公司来说似乎是明智之举,但重要的是要考虑是否所有级别的操作都需要雾计算。那么您应该什么时候实施雾计算?在当前的工业自动化和边缘网络之外,雾计算将成为大型连网系统的一个组成部分,并在数千或数百万连网设备之间共享数据。 45 | 46 | ## 3. AIoT 47 | 一个新的行业共识是:AIoT将成为未来二十年全球最重要的科技,是智慧建筑及智慧城市等新兴产业的重要基础。 48 | 49 | ## 4.全数字化管理+云服务 50 | 2018年,最应该引起你足够重视的趋势是“边云协同”。展望2019,最有望由此产生真正意义上的边缘连续体。 51 | 52 | 边缘连续体并不是指单个设备,而是由云、边、端构成的完整体系。云端和边缘不是相互竞争与替代的关系,它们都是互为依存、相互借力的边缘连续体的一部分。 53 | 54 | 边缘设备作为物联网云平台的“入口”,成为连通物理世界和数字世界的桥梁,是物联网产业的重要关口。通过由边缘与云端形成的多层混合架构而触发的“边云协同”效应,更能综合发挥两者的优势,促进物联网基础架构迎来一次全面的升级。 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /distributed_applications.md: -------------------------------------------------------------------------------- 1 | Lamport Clock如何启发人们在分布式系统中开始使用新的的思维方式, 并介绍了Sequential Consistency和Linearizability 2 | 3 | 4 | - Fault: 在系统中某一个步骤偏离正确的执行叫做一个fault, 比如内存写入错误, 但是如果内存是ECC的那么这个fault可以立刻被修复, 就不会导致error. 5 | - Error: 如果一个fault没能在结果影响到整个系统状态之前被修复, 结果导致系统的状态错误, 那么这就是一个error, 比如不带ECC的内存导致一个计算结果错误. 6 | - Failure: 如果一个系统的error没能在错误状态传递给其它节点之前被修复, 换句话说error被扩散出去了, 这就是一个failure. 7 | 8 | 9 | ### 分布式系统故障模型 10 | 在分布式系统中, 故障可能发生在节点或者通信链路上, 下面我们按照从最广泛最难的到最特定最简单的顺序列出故障类型: 11 | 12 | ``` 13 | byzantine failures: 这是最难处理的情况, 一个节点压根就不按照程序逻辑执行, 对它的调用会返回给你随意或者混乱的结果. 要解决拜占庭式故障需要有同步网络, 并且故障节点必须小于1/3, 通常只有某些特定领域才会考虑这种情况通过高冗余来消除故障. 关于拜占庭式故障你现在只要知道这是最难的情况, 稍后我们会更详细的介绍它. 14 | crash-recovery failures: 它比byzantine类故障加了一个限制, 那就是节点总是按照程序逻辑执行, 结果是正确的. 但是不保证消息返回的时间. 原因可能是crash后重启了, 网络中断了, 异步网络中的高延迟. 对于crash的情况还要分健忘(amnesia)和非健忘的两种情况. 对于健忘的情况, 是指这个crash的节点重启后没有完整的保存crash之前的状态信息, 非健忘是指这个节点crash之前能把状态完整的保存在持久存储上, 启动之后可以再次按照以前的状态继续执行和通信, 比如最基本版本的Paxos要求节点必须把ballot number记录到持久存储中, 一旦crash, 修复之后必须继续记住之前的ballot number. 15 | omission failures: 这种故障比crash-recovery多一个限制,就是发生故障后,消息不会恢复。比如网络故障造成某条消息在传输中丢失(而不是延迟). 16 | crash-stop failures: 也叫做crash failure或者fail-stop failures, 它比omission failure容易处理, 因为这种模型下故障就是crash, 并且这些故障不会恢复. 比如一个节点出现故障后立即停止接受和发送所有消息. 简单讲, 一旦发生故障, 这个节点就不会再和其它节点有任何交互. 就像他的名字描述的那样, crash and stop. 17 | ``` 18 | 19 | ### Consensus问题 20 | 21 | 之所以要介绍Consensus问题是因为Consensus问题是分布式系统中最基础最重要的问题之一, 也是应用最为广泛的问题, 他比其他的分布式系统的经典问题比如self-stabilization的实际应用要多, 我们可以通过介绍Consensus问题来更加深入得介绍一下之前提到的Linearizability和Sequential Consistency. 22 | 23 | Consensus所解决的最重要的典型应用是容错处理(fault tolerannce). 比如在原子广播(Atomic Broadcast)和状态机复制(State Machine Replication)的时候, 我们都要在某一个步骤中让一个系统中所有的节点对一个值达成一致, 这些都可以归纳为Consensus问题. 但是如果系统中存在故障, 我们要忽略掉这些故障节点的噪音让整个系统继续正确运行, 这就是fault tolerance. Consensus问题的难点就在于在异步网络中如何处理容错. 24 | 25 | Consensus问题的定义包含了三个方面, 一般的Consensus问题定义为: 26 | ``` 27 | termination: 所有进程最终会在有限步数中结束并选取一个值, 算法不会无尽执行下去. 28 | agreement: 所有非故障进程必须同意同一个值. 29 | validity: 最终达成一致的值必须是V1到Vn其中一个, 如果所有初始值都是vx, 那么最终结果也必须是vx. 30 | ``` 31 | 32 | ### FLP Impossibility, 1985 33 | 34 | 35 | --- 36 | 参考的paper 37 | - [One Hop Lookups for Peer-to-Peer Overlays](http://www.well.ox.ac.uk/~anjali/onehop.pdf) 38 | - [Pastry: Scalable, Decentralized Object Location, and 39 | Routing for Large-Scale Peer-to-Peer Systems](https://link.springer.com/content/pdf/10.1007%2F3-540-45518-3_18.pdf) 40 | - [pbft](https://www.usenix.org/legacy/events/osdi99/full_papers/castro/castro_html/node4.html#SECTION00040000000000000000) 41 | - [历史发展](http://danielw.cn/history-of-distributed-systems-2) 42 | - [time-clocks](https://lamport.azurewebsites.net/pubs/time-clocks.pdf) 43 | -------------------------------------------------------------------------------- /Open_Project.md: -------------------------------------------------------------------------------- 1 | ### 代码准备 2 | - 核心代码 3 | - 快速部署和运维代码 4 | - 快速入门项目 5 | - 项目脚手架(一键生成核心项目框架) 6 | - 热门语言SDK 7 | - 周边特性学习项目 8 | - 测试或者压测项目 9 | 10 | ### 文档准备 11 | - 项目产品文档(WiKi,readme) 12 | - 项目技术架构和概要文档 13 | - 用户快速入门文档 14 | - 生产部署合运维文档 15 | - 进阶文档,如:项目架构,模块解析文档,特性介绍文档 16 | - RoadMap规划 17 | - 贡献者说明文档 18 | - 周边产品配合使用说明文档 19 | 20 | ### 确定开源协议 21 | 用户可以根据自己的业务场景,确定需要选择的开源协议。 22 | 23 | ![image](https://image.520mwx.com/static/e1bd732c84754973e601745f6e68b019.jpg) 24 | 25 | GPL、BSD、MIT、Mozilla、Apache和LGPL 26 | 27 | ### 增加徽章 28 | 用户可以根据需要增加适用的徽章。 29 | #### 常用动态徽章 30 | ``` 31 | 持续集成状态 (Travis CI) 32 | Codacy 代码质量检查 33 | CodeFactor 代码质量检查 34 | 项目版本信息 35 | 开源协议 36 | 代码测试覆盖率 37 | 项目下载量 38 | 贡献者统计 39 | 安全检查: cobra 40 | ``` 41 | #### 自定义徽章 42 | 徽标图标格式 43 | ``` 44 | https://img.shields.io/badge/{徽标标题}-{徽标内容}-{徽标颜色}.svg 45 | ``` 46 | 47 | 带链接的徽标 48 | 49 | [![](https://img.shields.io/badge/{徽标标题}-{徽标内容}-{徽标颜色}.svg)]({linkUrl}) 50 | 51 | 徽标标题:徽标左边的文字 52 | 徽标内容:徽标右边的文字 53 | 徽标颜色:徽标右边的背景颜色,可以是颜色的16进制值,也可以是颜色英文。支持的颜色英文如下: 54 | 55 | 可以根据自己的需要定制一些自己的徽章,通过控制,增加更多样式。 56 | ``` 57 | https://img.shields.io/badge/{徽标标题}-{徽标内容}-{徽标颜色}.svg?{参数名1}={参数值1}&{参数名2}={参数值2} 58 | ``` 59 | 常用的 query string 参数有: 60 | ``` 61 | style:控制徽标主题样式,style的值可以是: plastic | flat | flat-square | social 。 62 | label:用来强制覆盖原有徽标的标题文字。 63 | colorA:控制左半部分背景颜色,只能用16进制颜色值作为参数,不能使用颜色英文。 64 | colorB:控制右半部分背景颜色。 65 | ``` 66 | 67 | - [更多信息,请查阅GitHub Badge](https://shields.io) 68 | 69 | 70 | ### 其他 71 | #### 测试覆盖率 72 | 73 | - C++项目: 74 | make test + codecov 75 | 76 | - Java项目: 77 | gradle test + jacoco + codecov 78 | 79 | - Rust项目: 80 | cargo test + codecov 81 | 使用codecov便于ci集成,报告都是以行和方法为单位生成覆盖率。 82 | 83 | ``` 84 | apply plugin: 'jacoco' 85 | 86 | jacocoTestReport { 87 | reports { 88 | xml.enabled true 89 | html.enabled true 90 | } 91 | afterEvaluate { 92 | classDirectories = files(classDirectories.files.collect { 93 | fileTree(dir: it, 94 | exclude: ['**/test/**','**/proto/**', '**/example/**']) 95 | }) 96 | } 97 | } 98 | ``` 99 | 100 | #### 贡献者管理 101 | 展示贡献者信息,可以[使用插件](https://allcontributors.org/docs/en/emoji-key) 102 | 103 | 104 | #### 徽章 105 | 106 | - 持续集成状态 (Travis CI) 107 | - Codacy 代码质量检查 108 | - CodeFactor 代码质量检查 109 | - 项目版本信息 110 | - 开源协议 111 | - 代码测试覆盖率 112 | - 项目下载量 113 | - 贡献者统计 114 | - 安全检查: cobra 115 | 116 | #### 开源运营 117 | ##### 社区渠道 118 | - 微信公众号 119 | - 微信群 120 | - 视频直播 121 | - 黑客松 122 | - 博客 123 | 124 | 125 | #### 痛点问题 126 | - 激励机制不足,完全靠社区推动很难 127 | - 提PR未必被合入或者符合要求,很多时候需要多个大咖支持,才能被关注 128 | - 沟通困难,语言障碍、时差不统一、文化差异、非实时沟通 129 | 130 | 131 | -------------------------------------------------------------------------------- /immersion.md: -------------------------------------------------------------------------------- 1 | A better approach is to create an immersion environment. 2 | 3 | You can create an immersive experience no matter where you live. 4 | 5 | An immersion environment is all about finding opportunities to bring the language into your current lifestyle and activities. 6 | 7 | One of the most common lifestyle elements we all share is the use of a tablet or smartphone. 8 | 9 | 10 | ### The stages of language acquisition by the way of language immersion 11 | 12 | Pre-production: It is also called “the silent period”. They are new L2 learners, this period will last 10 hours to 6 months in language immersion environment. They may have about 500 receptive word in their mind but can’t speak yet. This is a mimicking period. Students likely to repeat everything that they heard in class. They can respond to pictures and ‘yes or no’ questions by using their gestures like nod or shake head. The class needs to integrate pictures and physical response methods [6] 13 | 14 | Early Production: In early production stage, students can master about 1000 receptive and active words. This stage will last 6 month after pre-production stage. They can answer simple questions, like ‘Yes or no’ question, ‘are you hungry, Yes’ . They also can repeat and know how to use two word phrase like, put down. They maybe can not use the pattern correctly, but they can discover the problem. This is a self-discovery period.[13] 15 | 16 | Speech Emergence: In this stage, students will have about 3000 active words. It will last 1 years after early production stage. They can answer simple questions and use three or more words simple phrase and patterns. They can understand the general idea of a story with pictures. They may not can use the patterns correctly, but they can correct some by themselves. This is also called a self-correcting period. Teachers will focus on conversations part in class in this stage.[13] 17 | 18 | Intermediate Fluency: In this stage, students will have nearly 6000 active vocabulary. This stage will last 1 years after speech emergence. English language learners at the intermediate fluency stage have a vocabulary of 6000 active words. They start to use complex sentences in their speaking and writing. They also know how to respond others’ questions. It is not hard for them to use the target language to learn math and science subject. They are beginning to use more complex sentences when speaking and writing and are willing to express opinions and share their thoughts. They will ask questions to clarify what they are learning in class. More culture and literature stuffs will be taught in this stage.[13] 19 | Advanced Fluency (Continued Language Development): It is also called continued language development.[14] It requires students know most all content area vocabulary. This stage will last from 4–10 years. It is an achievement of cognitive academic language proficiency in the target language. Students second language ability arrived at near native level. 20 | -------------------------------------------------------------------------------- /给初学者的区块链学习资料.md: -------------------------------------------------------------------------------- 1 | ## 区块链资料汇总 2 | ### 关键术语 3 | - 区块链 4 | 5 | 区块链是一串通过验证的区块,当中的每一个区块都与上一个相连,一直连到创世区块。 确认当一项交易被区块收录时,我们可以说它有一次确认。矿工们在此区块之后每再产生一个区块,此项交易的确认数就再加一。当确认数达到六及以上时,通常认为这笔交易比较安全并难以逆转。 6 | 7 | - 比特币 8 | “比特币”既可以指这种虚拟货币单位,也指比特币网络或者网络节点使用的比特币软件。 区块 一个区块就是若干交易数据的集合,它会被标记上时间戳和之前一个区块的独特标记。区块头经过哈希运算后会生成一份工作量证明,从而验证区块中的交易。有效的区块经过全网络的共识后会被追加到主区块链中。 9 | 10 | - 加密算法 11 | 12 | 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。 该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程。 13 | 14 | - 分布式 15 | 16 | 分布式计算是一门计算机科学,它研究如何把计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果。分布式网络存储技术是将数据分散的存储于多台独立的机器设备上。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,不但解决了传统集中式存储系统中单存储服务器的瓶颈问题,还提高了系统的可靠性、可用性和扩展性。 17 | 18 | - 地址 19 | 比特币地址(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串字符和数字组成,以阿拉伯数字“1”开头。就像别人向你的email地址发送电子邮件一样,他可以通过你的比特币地址向你发送比特币。 20 | 21 | 22 | 23 | - 关键概念:[术语表](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%9C%AF%E8%AF%AD%E8%A1%A8.md) 24 | 25 | ### 2. 书籍 26 | - [精通比特币](https://github.com/bitcoinbook/bitcoinbook) 27 | - [Bitcoin and Cryptocurrency Technologies](https://lopp.net/pdf/princeton_bitcoin_book.pdf) 28 | 29 | ### 3. 体验动手搭建一个区块链 30 | - [fisco-bcos](https://github.com/FISCO-BCOS) 31 | 32 | ### 4. Paper 33 | - [Bitcoin: A Peer-to-Peer Electronic Cash System](https://bitcoin.org/bitcoin.pdf) 34 | - [ethereum-White-Paper](https://github.com/ethereum/wiki/wiki/White-Paper) 35 | 36 | ### 5. 学习智能合约 37 | 38 | - [solidity语法](https://solidity.readthedocs.io/en/v0.4.20/) 39 | - [smart-contract-best-practices](https://github.com/ConsenSys/smart-contract-best-practices) 40 | - [智能合约架构](https://github.com/FISCO-BCOS/Wiki/tree/master/%E6%B5%85%E8%B0%88%E4%BB%A5%E5%A4%AA%E5%9D%8A%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B8%8E%E5%8D%87%E7%BA%A7%E6%96%B9%E6%B3%95%EF%BB%BF) 41 | 42 | #### 5.1 智能合约开发工具 43 | - [在线工具remix](https://remix.ethereum.org/#optimize=false&version=soljson-v0.4.21+commit.dfe3193c.js) 44 | - vscode+solidity 45 | 46 | #### 5.2 智能合约框架 47 | - [truffle](https://github.com/trufflesuite/truffle) 48 | - [zeppelin-solidity](https://github.com/OpenZeppelin/zeppelin-solidity) 49 | 50 | #### 5.3智能合约实践 51 | #### 模拟器开发智能合约 52 | 测试开发:[EtherumJS TestRPC](https://github.com/trufflesuite/ganache-cli) 53 | 正式开发:[geth](https://github.com/ethereum/go-ethereum) 54 | 55 | - 在自己的私有链条上创建用户 56 | ``` 57 | geth --identity "newEth" --rpc --rpcaddr "0.0.0.0" --rpccorsdomain "*" --datadir "cdata" --port 30303 --rpcapi "personal,db,eth,net,web3" --networkid 999 --rpcport 8549 --targetgaslimit 4712388 console 58 | ``` 59 | - 创建账号和解锁账号 60 | ``` 61 | > eth.accounts 62 | > personal.newAccount("123456") 63 | > personal.unlockAccount(eth.accounts[0], "123456", 20*(60*1000)) 64 | ``` 65 | 66 | 更多:智能合约入门到精通,更对见[详细说明](https://segmentfault.com/a/1190000012996636) 67 | 68 | #### 使用truffle开发框架 69 | 1.框架说明: 70 | - [框架truffle API](http://truffleframework.com/) 71 | - 实践MetaCoin,具体的步骤参考官网 72 | 73 | 2.智能合约交互: 74 | - [重点理解合约交互](http://truffleframework.com/docs/getting_started/contracts) 75 | 76 | 3.solidity API 77 | - [solidity API](https://solidity.readthedocs.io/en/v0.4.20/) 78 | 79 | 80 | 4.智能合约相关规范 81 | - [使用包管理](http://truffleframework.com/docs/getting_started/packages-npm) 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /FRP_EDA.md: -------------------------------------------------------------------------------- 1 | ###### 知识准备 2 | - 🍪[什么是FRP](https://github.com/cristicmf/curious-cat/blob/master/%E8%AE%B2%E8%AE%B2FRP_FP.md) 3 | - 🍪[什么是EDA](https://github.com/cristicmf/curious-cat/blob/master/%E5%BD%93%E6%88%91%E5%9C%A8%E7%9C%8BEDA%E6%97%B6%E5%80%99.md) 4 | 5 | 6 | 7 | ## 分析 8 | 分析思路,因为我一直纠结于FRP和EDA是什么关系?他们的表现或者特性都是相似,但并非本体。下面我会从下面几个维度分析这个问题。 9 | 10 | 1. 语言本身的设计层面 11 | 2. 架构的设计层面 12 | 3. 商业的应用层面 13 | 4. 如果从生态架构层面 14 | 15 | 16 | 17 | ### 语言本身的设计层面 18 | ![image](https://www.researchgate.net/profile/Peter_Van_Roy/publication/241111987/figure/fig1/AS:298670202343424@1448219933039/Languages-paradigms-and-concepts.png) 19 | 20 | ``` 21 | But paradigms that have the power to express observable nondeterminism can be used 22 | to model real-world situations and to program independent activities. 23 | ``` 24 | 25 | 26 | The second key property of a paradigm is how strongly it supports state. State is the 27 | ability to remember information, or more precisely, to store a sequence of values in time. 28 | 29 | 30 | 31 | A single feedback loop consists of three concurrent components that interact with 32 | a subsystem (see Figure 6): a monitoring agent, a correcting agent, and an actuating 33 | agent. Realistic systems consist of many feedback loops. Since each subsystem must be 34 | as self-sucient as possible, there must be feedback loops at all levels. 35 | 36 | 37 | 38 | --- 39 | ``` 40 | There are two popular paradigms for concurrency. The rst is shared-state concur- 41 | rency: threads access shared data items using special control structures called monitors 42 | to manage concurrent access. 43 | ``` 44 | ``` 45 | The second 46 | paradigm is message-passing concurrency: concurrent agents each running in a single 47 | thread that send each other messages. The languages CSP (Communicating Sequential 48 | Processes) [25] and Erlang [6] use message passing. CSP processes send synchronous 49 | messages (the sending process waits until the receiving process has taken the message) 50 | and Erlang processes send asynchronous messages (the sending process does not wait). 51 | ``` 52 | 53 | ### Computer programming and system design 54 | 55 | 56 | 57 | ``` 58 | A CSP can be stated as follows: given a set of variables ranging 59 | over well-de ned domains and a set of constraints (logical relations) on those variables, 60 | nd an assignment of values to the variables that satis es all the constraints. 61 | 62 | ``` 63 | 64 | ### FRP && RP 65 | time 66 | ``` 67 | discrete instead of continuous 68 | ``` 69 | ###### example 70 | ``` 71 | OpenMusic has a mature language organized as three layers: functional, deterministic 72 | concurrency, and shared state. 73 | ``` 74 | 75 | ### 微观 76 | 77 | 78 | ### 宏观 79 | 80 | 81 | 82 | --- 83 | 84 | Programming Paradigms for Dummies: What Every Programmer Should Know 85 | - [What_Every_Programmer_Should_Know](https://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf) 86 | - 《SICP》 87 | - [Synchronous programming with events and relations: the SIGNAL language and its semantics](https://core.ac.uk/download/pdf/82752187.pdf) 88 | 89 | --- 90 | - [pvr](https://www.info.ucl.ac.be/~pvr/cvvanroy.html) 91 | 92 | 93 | --- 94 | 1. 如果完全考虑事件这个因素,必然是一个... 95 | 2. 能够表达现实当中的一个场景或者一个现象 96 | 3. 反馈系统和监控系统 97 | 98 | 99 | --- 100 | 101 | The research projects address some of the key technological challenges of our time, mainly but not exclusively: ubiquitous data-intensive applications, scalable distributed systems (including Cloud computing and P2P models), adaptive distributed systems (autonomic computing, green computing, decentralized and voluntary computing), and applied distributed systems (distributed algorithms and systems, working in an inter-disciplinary manner, in existing and emerging fields to address industrial and societal needs in the European and worldwide context. 102 | 103 | 104 | -------------------------------------------------------------------------------- /docker.md: -------------------------------------------------------------------------------- 1 | # 脚本化一键部署 2 | ## Docker 3 | - install Docker 4 | 5 | 参照官网 6 | 7 | - install kubernetes 8 | 9 | 安装kubernetes的时候,需要安装kubelet, kubeadm等包,但k8s官网给的yum源是packages.cloud.google.com,国内访问不了,此时我们可以使用阿里云的yum仓库镜像。 10 | 11 | 12 | 阿里云上没有附Help说明连接,简单摸索了下,如下设置可用(centos)。注意不要开启check。 13 | ``` 14 | cat < /etc/yum.repos.d/kubernetes.repo 15 | [kubernetes] 16 | name=Kubernetes 17 | baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 18 | enabled=1 19 | gpgcheck=0 20 | repo_gpgcheck=0 21 | gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg 22 | ``` 23 | 24 | 25 | 26 | ## 开发思路 27 | ``` 28 | 1 寻找基础镜像 29 | 2 基于基础镜像编写Dockerfile脚本 30 | 3 根据Dockerfile脚本创建项目镜像 31 | 4 将创建的镜像推送到docker仓库 (根据自身需要,可做可不做) 32 | 5 基于项目镜像创建并运行docker容器 (实现最终部署) 33 | ``` 34 | 35 | 思路:使用 centos 容器安装对应的软件环境,最后将环境导出。 36 | 37 | ### 操作步骤 38 | 39 | 1. 创建容器 40 | ``` 41 | $ docker pull centos 42 | $ sudo docker run --privileged --cap-add SYS_ADMIN -e container=docker -it --name my_centos -p 80:8080 -d --restart=always centos:7 /usr/sbin/init 43 | ``` 44 | 45 | 2. 启动容器 46 | ``` 47 | $ docker exec -it my_centos /bin/bash 48 | ``` 49 | 50 | 3. 导出和导入 51 | ``` 52 | $ docker export my_centos > /data/app/meifen/my_centos-export-0428.tar 53 | 54 | $ docker import /data/app/meifen/my_centos-export-0428.tar 55 | 56 | ``` 57 | 58 | 4. 保存save 59 | 60 | 格式:docker save IMAGE(镜像) 61 | 62 | 使用 docker images 查看本机已有的镜像(也可以使用 docker commit 命令把一个正在运行的容器保存为镜像) 63 | 64 | ``` 65 | $ docker save 9610cfc68e8d > /data/app/meifen/my_centos-export-0428.tar 66 | ``` 67 | - 加载 load 68 | 有点慢,稍微等待一下,没有任何warn信息就表示保存OK。9610cfc68e8d 是镜像ID 69 | 70 | 71 | 现在就可以在任何装 docker 的地方加载 刚保存的镜像了 72 | 73 | ``` 74 | $ docker load < /home/my_centos-export-0428.tar 75 | ``` 76 | 77 | 78 | **其他说明** 79 | 镜像和容器 导出和导入的区别 80 | 81 | 1 容器导入 是将当前容器变成一个新的镜像 82 | 2 镜像导入 是复制的过程 83 | 84 | save 和 export区别 85 | 86 | 1 save 保存镜像所有的信息-包含历史 87 | 2 export 只导出当前的信息 88 | 89 | export导出的镜像文件大小 小于 save保存的镜像。export 导出(import导入)是根据容器拿到的镜像,再导入时会丢失镜像所有的历史,所以无法进行回滚操作(docker tag );而save保存(load加载)的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。(查看方式:docker images --tree) 。export 只导出当前的信息 90 | 91 | ## 提交Docker-hub 92 | 1. 提交镜像 93 | ``` 94 | $ docker commit -a "cristic" -m "commit content" 801a40ffa673 cristicmei/name:v1.0.0 95 | ``` 96 | 97 | 2. 查看镜像 98 | ``` 99 | $ docker images 100 | ``` 101 | 3. 登录docker-hub 102 | ``` 103 | $ docker image 104 | ``` 105 | 前提是用户有docker-hub的账号 106 | 107 | 4. 提交远程仓库 108 | ``` 109 | $ docker push cristicmei/name:v1.0.0 110 | ``` 111 | ## 精简Docker镜像大小的必要性 112 | 113 | Docker镜像由很多镜像层(Layers)组成(最多127层),镜像层依赖于一系列的底层技术,比如文件系统(filesystems)、写时复制(copy-on-write)、联合挂载(union mounts)等技术,可以查看Docker社区文档以了解更多有关Docker存储驱动的内容,这里不再赘述。总的来说,Dockerfile中的每条指令都会创建一个镜像层,继而会增加整体镜像的尺寸。 114 | 115 | 下面是精简Docker镜像尺寸的好处: 116 | ``` 117 | 减少构建时间 118 | 减少磁盘使用量 119 | 减少下载时间 120 | 因为包含文件少,攻击面减小,提高了安全性 121 | 提高部署速度 122 | ``` 123 | 124 | - 最重要的因素是减少镜像的层数,这样能大大减小镜像的大小; 125 | 126 | 使用链式代码“&&”把多行指令结合成一行 127 | 128 | - 清除 yum 缓存 129 | ``` 130 | $ yum clean headers 131 | $ yum clean packages 132 | $ yum clean all 133 | ``` 134 | 135 | - 清除无用的tar.gz安装包 136 | - 选择更小的基础镜像 137 | 138 | ## docker 架构说明 139 | ![image](https://www.hi-linux.com/img/linux/docker-arch1.jpg) 140 | 141 | [更多架构说明](https://www.hi-linux.com/posts/13732.html) 142 | 143 | 144 | 145 | 146 | ## ISSUE 147 | 148 | #### /var/lib/docker/overlay2 占用很大,清理Docker占用的磁盘空间,迁移 /var/lib/docker 目录 149 | 150 | 1.命令查看磁盘使用情况 151 | ``` 152 | $ du -hs /var/lib/docker/ 153 | ``` 154 | 155 | 用于查看Docker的磁盘使用情况 156 | ``` 157 | $ docker system df 158 | 159 | ``` 160 | 161 | 162 | 2. 清理磁盘 163 | 164 | ``` 165 | $ docker system prune 166 | ``` 167 | 可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)。 168 | 169 | ``` 170 | $ docker system prune -a 171 | ``` 172 | 173 | 3. 迁移 /var/lib/docker 目录 174 | 175 | 176 | -------------------------------------------------------------------------------- /docker-mysql-install.md: -------------------------------------------------------------------------------- 1 | 1.下载mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz的安装包 2 | 3 | ``` 4 | 5 | ``` 6 | 2.解压mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz 7 | ``` 8 | # tar -xvf mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz 9 | ``` 10 | 3.将解压的文件重命名mysql,并移动到/usr/local目录下 11 | 12 | ``` 13 | # mv mysql-8.0.13-linux-glibc2.12-x86_64 mysql 14 | # mv mysql /usr/local/ 15 | ``` 16 | 17 | 4.进入到/usr/local目录下,创建用户和用户组并授权 18 | ``` 19 | # cd /usr/local/ 20 | # groupadd mysql 21 | # useradd -r -g mysql mysql 22 | # cd mysql/ #注意:进入mysql文件下授权所有的文件 23 | # chown -R mysql:mysql ./ 24 | ``` 25 | 26 | 5.再/usr/local/mysql目录下,创建data文件夹 27 | ``` 28 | # mkdir data 29 | ``` 30 | 31 | 6.初始化数据库,并会自动生成随机密码,记下等下登陆要用 32 | ``` 33 | # bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data 34 | ``` 35 | 7.修改/usr/local/mysql当前目录得用户 36 | ``` 37 | 38 | 如果出现 `error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory`。解决问题具体操作如下。 39 | yum -y install libnuma.so.1 40 | yum -y install numactl 41 | ``` 42 | 43 | 44 | 45 | ``` 46 | 47 | # chown -R root:root ./ 48 | # chown -R mysql:mysql data 49 | ``` 50 | 8.复制文件my.cnf,开始是没有my-default.cnf这个文件,需要手动创建。可以用# touch my-default.cnf命令创建一个,并配置权限。 51 | ``` 52 | # cd support-files/ 53 | # touch my-default.cnf 54 | # chmod 777 ./my-default.cnf 55 | # cd ../ 56 | # cp support-files/my-default.cnf /etc/my.cnf 57 | ``` 58 | 配置my.cnf 59 | 60 | ``` 61 | # vim /etc/my.cnf 62 | [mysqld] 63 | 64 | # Remove leading # and set to the amount of RAM for the most important data 65 | # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. 66 | # innodb_buffer_pool_size = 128M 67 | 68 | # Remove leading # to turn on a very important data integrity option: logging 69 | # changes to the binary log between backups. 70 | # log_bin 71 | 72 | # These are commonly set, remove the # and set as required. 73 | basedir = /usr/local/mysql 74 | datadir = /usr/local/mysql/data 75 | socket = /tmp/mysql.sock 76 | log-error = /usr/local/mysql/data/error.log 77 | pid-file = /usr/local/mysql/data/mysql.pid 78 | tmpdir = /tmp 79 | port = 3306 80 | #lower_case_table_names = 1 81 | # server_id = ..... 82 | # socket = ..... 83 | #lower_case_table_names = 1 84 | max_allowed_packet=32M 85 | default-authentication-plugin = mysql_native_password 86 | #lower_case_file_system = on 87 | #lower_case_table_names = 1 88 | log_bin_trust_function_creators = ON 89 | # Remove leading # to set options mainly useful for reporting servers. 90 | # The server defaults are faster for transactions and fast SELECTs. 91 | # Adjust sizes as needed, experiment to find the optimal values. 92 | # join_buffer_size = 128M 93 | # sort_buffer_size = 2M 94 | # read_rnd_buffer_size = 2M 95 | 96 | sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 97 | ``` 98 | 如果后期mysql运行报错,可以直接到log-error = /usr/local/mysql/data/error.log目录下直接查看错误日志 99 | 100 | 命令:cat /usr/local/mysql/data/error.log 101 | 102 | 103 | 10.开机自启,进入/usr/local/mysql/support-files进行设置 104 | ``` 105 | # cd support-files/ 106 | # cp mysql.server /etc/init.d/mysql 107 | # chmod +x /etc/init.d/mysql 108 | ``` 109 | 11.注册服务 110 | ``` 111 | # chkconfig --add mysql 112 | ``` 113 | 114 | 12.etc/ld.so.conf要配置路径,不然报错 115 | 116 | ``` 117 | # vim /etc/ld.so.conf 118 | 119 | 添加如下内容: 120 | /usr/local/mysql/lib 121 | ``` 122 | 123 | 13.配置环境变量 124 | 125 | ``` 126 | # vim /etc/profile 127 | # source /etc/profile 128 | 129 | 添加如下内容: 130 | #MYSQL ENVIRONMENT 131 | export PATH=$PATH:/usr/local/mysql/bin:/usr/local/mysql/lib 132 | ``` 133 | 如果每次退出容器,需要`source /etc/profile` 134 | 135 | 14. 启动服务 136 | ``` 137 | # cp -a ./support-files/mysql.server /etc/init.d/mysqld 138 | # cd bin/ 139 | # ./mysqld_safe --user=mysql & 140 | # /etc/init.d/mysqld restart 141 | ``` 142 | 143 | 15.登陆,这里输入上面第6步随机生成得密码,细心点输入,没有显示的,登陆成功如图所示 144 | ``` 145 | # mysql -uroot -p 146 | ... 147 | 密码 148 | ... 149 | ``` 150 | 151 | 如果失败,出现`/tmp/mysql.sock`。 首先删除`/tmp/mysql.sock`,然后给目录授权 `chown -R mysql.mysql /tmp/* ` 。 152 | 153 | ``` 154 | # rm -rf /tmp/mysql.sock 155 | # chown -R mysql.mysql /tmp/* 156 | ``` 157 | 如果出现,无法登陆的情况修改my.cnf文件。`[mysqld]`后面任意一行添加“skip-grant-tables”用来跳过密码验证的过程。 158 | 159 | ``` 160 | # vim /etc/my.cnf 161 | ... 162 | ... 163 | ``` 164 | 165 | 重启服务 166 | ``` 167 | # /etc/init.d/mysqld restart 168 | ``` 169 | 170 | 重新设置密码 171 | ``` 172 | # mysql 173 | mysql> use mysql; 174 | mysql> alter user user() identified by "123456"; 175 | 176 | mysql> flush privileges; 177 | mysql> quit 178 | ``` 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /fisco-bcos-resources.md: -------------------------------------------------------------------------------- 1 | # FISCO-BCOS Resources 2 | 3 | ## 实践步骤 4 | 5 | 1. 部署区块链,[指导手册](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html) 6 | 2. 合约开发,[指导手册](https://segmentfault.com/a/1190000012996636) 7 | 3. 应用开发脚手架,[项目下载和指导手册](https://github.com/FISCO-BCOS/spring-boot-starter) 8 | 4. 体验案例,[存证](https://github.com/FISCO-BCOS/evidenceSample) 9 | 5. 其他,体验分布式身份标识[WeIdentity](https://github.com/WeBankFinTech/WeIdentity)和体验物联网连接器[WeEvent](https://github.com/WeBankFinTech/WeEvent) 10 | 11 | ### 系统要求 12 | 13 | | 配置 | 最低配置 | 推荐配置 | 14 | | -------- | ----------------- | ------------------------------------------------------------ | 15 | | CPU | 2核 1.5GHz | 4核 2.4GHz | 16 | | 内存 | 2G | 4GB | 17 | | 带宽 | 1M | 5M | 18 | | Java | Java(TM) 1.8 | 推荐`Oralce JDK`;
如果在`CentOS`中使用`Open JDK`,请先升级到`1.9` | 19 | | 操作系统 | 能正常运行JVM即可 | 快速安装Bash脚本在以下环境测试通过:
`CentOS7.2 + `、`Ubuntu16.04`、`RedHat7.4`
`Java`服务在以下环境测试通过:
`CentOS7.2`、`Ubuntu16.04`、`RedHat7.4` | 20 | 21 | ### 文档 22 | 23 | #### 单机部署区块链 24 | 进行开发、测试,以及演示的时,可以使用单机模拟 25 | - [单机部署指导手册](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html) 26 | - [FISCO-BCOS源码地址](https://github.com/FISCO-BCOS/FISCO-BCOS) 27 | 28 | #### 应用开发脚手架 29 | 开发者可以通过下载脚手架,进行配置修改可以直接进行开发。 30 | 31 | 该项目是基于`Web3SDK`的`spring boot`版本的示例项目。提供`FISCO BCOS`区块链应用开发的基本框架和基本的测试案例,帮助开发者基于 `FISCO BCOS`区块链快速进行应用开发。此版本只支持`FISCO BCOS 2.0`。 32 | 33 | - [项目文档和地址](https://github.com/FISCO-BCOS/spring-boot-starter) 34 | 35 | #### 区块链开发工具集 36 | 37 | 1. Web3SDK 38 | Web3SDK为FISCO BCOS提供Java API。利用FISCO BCOS JAVA SDK可以简单快捷的基于FISCO-BCOS进行区块链应用开发。 39 | - [操作文档](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/sdk.html) 40 | - [源码地址](https://github.com/FISCO-BCOS/web3sdk) 41 | 42 | 2. Python SDK 43 | Python SDK为FISCO BCOS提供Python API,使用FISCO BCOS Python SDK可以简单快捷的基于FISCO-BCOS进行区块链应用开发。 44 | - [项目文档和代码](https://github.com/FISCO-BCOS/python-sdk) 45 | 46 | 3. Nodejs SDK 47 | Node.js SDK为FISCO BCOS提供Node.js API,使用FISCO BCOS Node.js SDK可以简单快捷地基于FISCO-BCOS进行区块链应用开发。 48 | - [项目文档和代码](https://github.com/FISCO-BCOS/nodejs-sdk) 49 | 50 | 4. console 51 | console 控制台是FISCO BCOS 2.0的重要交互式客户端工具。控制台拥有丰富的命令,包括查询区块链状态、管理区块链节点、部署并调用合约等。 52 | - [操作文档](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html#id7) 53 | - [源码](https://github.com/FISCO-BCOS/console) 54 | 55 | 56 | #### WeBASE 57 | 58 | WeBase是在区块链应用和FISCO BCOS节点之间搭建的一套通用组件,围绕交易、合约、密钥管理,数据,可视化管理来设计各个模块;开发者可以根据业务所需,选择子系统进行部署。 59 | 60 | - [产品文档](https://github.com/WeBankFinTech/WeBASE) 61 | - [源码地址](https://github.com/WeBankFinTech/WeBASE) 62 | - [在线文档](https://webasedoc.readthedocs.io/zh_CN/latest/index.html) 63 | 64 | 65 | 66 | #### WeIdentity 67 | 68 | WeIdentity是一套基于区块链的分布式多中心的技术解决方案,提供分布式实体身份标识及管理、可信数据交换协议等一系列的基础层与应用接口,可实现实体对象(人或物)数据的安全授权与交换。 69 | 70 | - [产品文档](https://fintech.webank.com/weidentity) 71 | - [源码地址](https://github.com/WeBankFinTech/WeIdentity) 72 | - [在线文档](https://weidentity.readthedocs.io/zh_CN/latest/) 73 | 74 | #### WeEvent 75 | 76 | WeEvent是一套分布式事件驱动架构,实现了可信、可靠、高效的跨机构、跨平台事件通知机制。秉承分布式商业模式中对等合作、智能协同、价值共享的设计理念,致力于提升机构间合作效率,降低合作成本,同时打通应用程序、物联网、云服务和私有服务等不同平台,最终在不改变已有商业系统的开发语言、接入协议的情况下,做到跨机构、跨平台的事件通知与处理。 77 | 78 | - [产品文档](https://fintech.webank.com/weevent) 79 | - [源码地址](https://github.com/WeBankFinTech/WeEvent) 80 | - [在线文档](https://weeventdoc.readthedocs.io/zh_CN/latest/) 81 | 82 | #### WeCross 83 | 84 | WeCross是分布式商业区块链跨链协作平台。该平台能解决业界主流的区块链产品间接口不互通、无法协作的问题,以及区块链系统无法平行扩展、计算能力和存储容量存在瓶颈等问题。WeCross作为未来分布式商业区块链互联的基础架构,秉承公众联盟链多方参与、共享资源、智能协同和价值整合的理念,致力于促进跨行业、机构和地域的跨区块链价值交换和商业合作,实现了高效、通用和安全的区块链跨链协作机制。 85 | 86 | - [产品文档](https://fintech.webank.com/wecross/) 87 | - [源码地址](https://github.com/WeBankFinTech/WeCross) 88 | - [在线文档](https://wecross.readthedocs.io/zh_CN/latest/) 89 | 90 | 91 | #### 应用落地情况 92 | 93 | FISCO BCOS已落地应用达数十个,场景覆盖政务、金融、公益、医疗、教育、交通、版权、商品溯源、供应链、招聘、农业、社交、游戏等多个领域,如: 94 | 95 | - 金融业:机构间对账、供应链金融、旅游金融等。 96 | - 司法服务:仲裁链、电子借据等。 97 | - 文化版权:版权存证与交易等。 98 | - 社会管理:不动产登记等。 99 | 100 | 此处提供一些具有代表性的[落地应用案](https://mp.weixin.qq.com/s/vUSq80LkhF8yCfUF7AILgQ) 101 | 102 | 103 | 104 | #### 更多材料 105 | 106 | - [智能合约开发说明文档](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/smart_contract.html) 107 | - [智能合约语法介绍](https://solidity.readthedocs.io/en/v0.4.25/solidity-by-example.html) 108 | - [SDK使用sample](https://github.com/FISCO-BCOS/evidenceSample) 109 | - [参数说明和配置解释](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/sdk.html) 110 | -------------------------------------------------------------------------------- /Shell.md: -------------------------------------------------------------------------------- 1 | # 常用shell命令 2 | ## 网络 3 | ### 查看网络 4 | ``` 5 | $ netstat 6 | $ netstat ip port 7 | ``` 8 | ### 抓包 9 | 10 | ``` 11 | $ tcpdump -Xns0 port 9229 12 | ``` 13 | ### 查看端口 14 | ``` 15 | $ ps -ef|grep port 16 | $ lsof -i:port 17 | ``` 18 | ### 查看外网ip 19 | ``` 20 | $ curl ifconfig.me/all.xml 21 | ``` 22 | --- 23 | ## 文件 24 | ### md5sum文件校验 25 | ``` 26 | $ md5sum file 27 | ``` 28 | ### 在线格式化文件 29 | ``` 30 | $ python -m json.tool somejson.txt 31 | ``` 32 | 33 | ### 打包和压缩文件 34 | #### zip 35 | ``` 36 | $ zip -r ./xahot.zip ./* -r表示递归 37 | $ zip [参数] [打包后的文件名] [打包的目录路径] 38 | 39 | $ zip –q –r xahot.zip /home/wwwroot/xahot 40 | ``` 41 | 42 | #### tar 43 | ``` 44 | $ tar zcvf FileName.tar.gz DirName 45 | ``` 46 | 47 | ### 文件操作 48 | ``` 49 | $ tail -f 文件 50 | ``` 51 | --- 52 | ## 系统相关 53 | ### 查看内存 54 | ``` 55 | $ df -h 56 | $ du -sh * 57 | ``` 58 | ### 分析内存 59 | ``` 60 | $ top 61 | $ ps 62 | ``` 63 | ### 查看僵尸进程 64 | ``` 65 | ps -ef|grep defunct 66 | ``` 67 | 68 | ### 远程拷贝 69 | scp [参数] [原路径] [目标路径] 70 | ``` 71 | $ scp -r file.tar.gz path 72 | ``` 73 | 74 | ## 进程 75 | ### 查看进程所在目录 76 | ``` 77 | $ ll /proc/pid 78 | ``` 79 | ## 用户分组和权限管理 80 | ### 创建用户 81 | ``` 82 | $ useradd testuser 83 | ``` 84 | ### 给用户设置密码 85 | ``` 86 | $ passwd testuser 87 | ``` 88 | ### $PATH 89 | $PATH:决定了shell将到哪些目录中寻找命令或程序,PATH的值是一系列目录,当您运行一个程序时,Linux在这些目录下进行搜寻编译链接。 90 | #### 查看环境变量 91 | ``` 92 | $ echo $PATH 93 | ``` 94 | #### 添加环境变量 95 | ``` 96 | $ export PATH=/opt/STM/STLinux-2.3/devkit/sh4/bin:$PATH 97 | ``` 98 | 99 | ###### 相关文件说明 100 | 101 | - 与用户(user)相关的配置文件; /etc/passwd 注:用户(user)的配置文件; /etc/shadow 注:用户(user)影子口令文件; 102 | - 与用户组(group)相关的配置文件; /etc/group 注:用户组(group)配置文件; /etc/gshadow 注:用户组(group)的影子文件 103 | 104 | --- 105 | ## Vim 106 | vim 技巧 107 | - 格式化全文指令  gg=G 108 | - 自动缩进当前行指令  == 109 | - 格式化当前光标接下来的8行  8= 110 | - 格式化选定的行  v 111 | - 选中需要格式化的代码段 = 112 | - 113 | :$ 跳转到最后一行 114 | :1 跳转到第一行 115 | 第二种方式 116 | 117 | shift+g 跳转到最后一行 118 | gg 跳转到第一行 119 | 120 | 121 | 122 | 123 | --- 124 | ooooooo 125 | 方便日后用,主要是在my.ini文件中,配置skip-grant-tables,略过验证,然后再更新里面的密码设置。 126 | 具体步骤: 127 | 1、修改my.ini配置文件,添加skip-grant-tables 128 | 2、重启mysql服务 129 | 3、登录mysql,并设定新的密码 130 | 4、删除my.ini配置文件中的skip-grant-tables 131 | 5、重启mysql服务并登录 132 | 133 | 1. 修改my.ini配置文件,添加skip-grant-tables 134 | ``` 135 | #编辑mysql配置文件 136 | vim /etc/my.cnf 137 | 138 | #添加 139 | skip-grant-tables 140 | ``` 141 | 142 | 2、重启mysql服务 143 | ``` 144 | service mysql restart 145 | 146 | #新的mysql执行这个命令 147 | systemctl restart mysqld.service 148 | ``` 149 | 150 | 3、登录mysql,并设定新的密码 151 | ``` 152 | #连接mysql,直接回车即可,不需要输入密码 153 | mysql -u root -p 154 | 155 | #更新root用户密码 156 | update mysql.user set authentication_string=password('yellowcong') where user='root' and Host = 'localhost'; 157 | 158 | #刷新权限 159 | flush privileges; 160 | 161 | #推出mysql 162 | exit 或者 quit 163 | 164 | ``` 165 | 4、删除my.ini配置文件中的skip-grant-tables 166 | ``` 167 | vim /etc/my.cnf 168 | 169 | #注释掉skip-grant-tables 170 | ``` 171 | 5、重启mysql服务并登录 172 | 173 | ``` 174 | service mysql restart 175 | mysql -uroot -pyellowcong 176 | ``` 177 | 178 | --- 179 | crudini 180 | ``` 181 | crudini --set [--existing] config_file section [param] [value] 182 | crudini --get [--format=sh|ini] config_file [section] [param] 183 | crudini --del [--existing] config_file section [param] 184 | crudini --merge [--existing] config_file [section] 185 | ``` 186 | 187 | 188 | ## 安装JDK 189 | #### 下载 190 | https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 191 | 192 | #### 二、卸载已有jdk 193 | 194 | 1.查看已安装jdk: rpm -qa|grep java 195 | 196 | [root@localhost software]# rpm -qa|grep java 197 | ``` 198 | java-1.7.0-openjdk-1.7.0.45-2.4.3.3.el6.x86_64 199 | java-1.6.0-openjdk-1.6.0.0-1.66.1.13.0.el6.x86_64 200 | tzdata-java-2013g-1.el6.noarch 201 | ``` 202 | 203 | 2.卸载已有jdk: 204 | ``` 205 | rpm -e --nodeps java-1.7.0-openjdk-1.7.0.45-2.4.3.3.el6.x86_64 java-1.6.0-openjdk-1.6.0.0-1.66.1.13.0.el6.x86_64 tzdata-java-2013g-1.el6.noarch 206 | ``` 207 | 208 | 注:如果使用 rpm -qa|grep java 命令没有查到jdk包,但是使用 java -version 命令却可以看到jdk版本,可以使用 which java 命令查看 java 命令的执行路径,然后找到对应的jdk文件并删除。 209 | 210 | #### 三、安装jdk 211 | 212 | 1.将下载好的安装包 jdk-8u211-linux-x64.tar.gz 上传到服务器指定目录下; 213 | 214 | 2.解压安装包: tar -zxvf jdk-8u211-linux-x64.tar.gz 215 | 216 | 3.复制安装包到 /usr/local/java/ 目录下: 217 | ``` 218 | cp -r jdk1.8.0_211/ /usr/local/java 219 | cd /usr/local/java 220 | mv jdk1.8.0_211 jdk1.8 221 | ``` 222 | 223 | 4.添加环境变量:编辑 /etc/profile 文件: vim /etc/profile ,在最后面添加: 224 | ``` 225 | JAVA_HOME=/usr/local/java/jdk1.8 226 | CLASSPATH=$JAVA_HOME/lib/ 227 | PATH=$PATH:$JAVA_HOME/bin 228 | ``` 229 | export PATH JAVA_HOME CLASSPATH 230 | 5.重新加载 /etc/profile 文件 source /etc/profile 231 | 232 | 6.使用 java -version 命令验证jdk是否安装成功: 233 | 234 | [root@localhost java]# java -version 235 | ``` 236 | java version "1.8.0_211" 237 | Java(TM) SE Runtime Environment (build 1.8.0_211-b12) 238 | Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode) 239 | ``` 240 | -------------------------------------------------------------------------------- /Complex_Event_Processing_and_Streaming_Data_Analytics.md: -------------------------------------------------------------------------------- 1 | # Complex_Event_Processing_and_Streaming_Data_Analytics 2 | 3 | ## 背景 4 | 5 | - Streaming Data Analytics 6 | 7 | [Forrester](https://reprints.forrester.com/#/assets/2/202/'RES136545'/reports) defines Streaming Analytics as: 8 | 9 | > Software that provides analytical operators to **orchestrate data flow**, **calculate analytics**, and **detect patterns** on event data **from multiple, disparate live data sources** to allow developers to build applications that **sense, think, and act in real time**. 10 | 11 | 12 | 13 | - Complex Event Processing (CEP) 14 | 15 | [Gartner’s IT Glossary](https://www.gartner.com/it-glossary/complex-event-processing) defines CEP as follows: 16 | 17 | > "CEP is a kind of computing in which **incoming data about events is distilled into more useful, higher level “complex” event data** that provides insight into what is happening." 18 | > 19 | > "**CEP is event-driven** because the computation is triggered by the receipt of event data. CEP is used for highly demanding, continuous-intelligence applications that enhance situation awareness and support real-time decisions." 20 | 21 | 22 | 23 | Factor:主要包含Complex Event Processing (CEP)和Streaming Data Analytics。 24 | 25 | 26 | 27 | 28 | ### 说明 29 | 30 | #### 定义 31 | 32 | 总体而言规则引擎是一种简单的推理机,应用上可以将规则引擎作为一种组件潜入到系统中(例如工作流引擎),从而将**业务决策**从**应用程序代**码中分离出来,并使用预定义的规则语言编写业务决策。使用规则引擎带来的好处是: 33 | 34 | - 避免业务规则变化带来的重新编译和重新部署的问题; 35 | - 使用声明性编程方法,提高业务规则代码的可读性; 36 | - 开发人员不需要过多关注业务逻辑(根据各种情况判断发生了什么事情),可以专注于应用逻辑(在发生了什么事情时进行什么样的处理),很多场景下可以提供给非专业开发人员使用; 37 | 38 | #### 组成 39 | 40 | - 规则定义组件: 使用该组件提供的处理语言 定义特定规则,订阅topic,完成后存储入规则库。 41 | 42 | - 规则库组件: 存储已经定义好的规则 43 | 44 | - 复杂事件检测组件:核心模块对输入的数据流序列进行过滤、结合、聚集、关联等操作。匹配成功后生成新的事物序列执行输出操作 45 | 46 | ​ 47 | 48 | #### 框架分析和选型 49 | 50 | | 类型 | 简述 | 常用组件 | 51 | | --------- | ---------------------------------------- | ------------------ | 52 | | 组合操作表达式 | 通过使用不同组合操作符将单个事件进行组合并在此基础上进行表达式嵌套来描述复杂事件 | Aviator、easy-rules | 53 | | 数据流查询语言 | 对SQL结构化查询语言的拓展,将输入流中的时间转换为数据库中关系,然后在这些关系上执行查询,最后将查询结果转换为数据流(CEP引擎) | Esper | 54 | | 产生式规则 | 指定当特定状态到达时应该执行的相应活动,推理过程与CEP处理过程相似 | Drools | 55 | | CEP+事实数据流 | native Streaming 、Complex Event Processing engine that understands Streaming SQL queries in order to capture events from diverse data sources | Siddhi、Flink | 56 | 57 | | 名称 | 语言、协议、质量 | 特点 | 58 | | ---------- | ------------------------ | ---------------------------------------- | 59 | | Aviator | java、*、低 | | 60 | | easy rules | java、apache 2.0、中 | 简单容易上手 | 61 | | Esper | java、net、GUN2.0、中 | 轻量级解决方案、可以方便嵌入服务中心,提供CEP功能 。**单机全内存方案,需要整合其他分布式和存储。** 以内存实现时间窗功能,无法支持较长跨度的时间窗。 无法有效支持定时触达(如用户在浏览发生后30分钟触达支付条件判断)。 | 62 | | Drools | java、apache2.0、中 | 老牌、稳定。 功能较为完善,具有如系统监控、操作平台等功能。 **学习曲线陡峭,其引入的DRL语言较复杂,独立的系统很难进行二次开发。** 以内存实现时间窗功能,无法支持较长跨度的时间窗。 无法有效支持定时触达(如用户在浏览发生后30分钟触达支付条件判断)。 | 63 | | Siddhi | java、Python 、apache2.0、高 | 容易上手、HA、Gartner | 64 | | Flink | java、apache2.0、高 | 云服务、apache、大厂商、HA | 65 | | | | | 66 | | | | | 67 | | | | | 68 | 69 | 70 | 71 | #### Siddhi Vs Flink 72 | 73 | | Factor | Siddhi | Flink | 74 | | ------ | ---------------------------------------- | ---------------------------------------- | 75 | | 依赖 | Zookeeper, Kubernetes (NATS, gRPC, Prometheus),messaging systems (NATS, Kafka, JMS), Databases (RDBMS, NoSQL), Services (HTTP, gRPC), File systems and others | clusters(Optional Hadoop YARN、 Apache Mesos 、Kubernetes) 、Zookeeper、Kafka Connector | 76 | | 核心仓库 | siddhi-core, siddhi-query-api, siddhi-query-compiler, and siddhi-annotations. | flink-java、flink-streaming-java_2.11、flink-clients_2.11、flink-connector-wikiedits_2.11、flink-connector-kafka-0.11_2.11 | 77 | | 扩展 | 配置组件 | 插件化扩展 | 78 | | 运维 | | 1. 7*24 小时稳定运行;2. 检查点的一致性、高效的检查点、端到端的精确一次、集成多中级群管理服务、内存高可用;3. Flink能够方便地升级、迁移、暂停、恢复应用服务;4. 监控和控制应用服务 | 79 | | 端口占用 | 可配置 8280 | high-availability.zookeeper.quorum: localhost:2181 , server.0=localhost:2888:3888 | 80 | | 内存资源占用 | Memory(128 MB ~500 MB), Cores( 2 cores recommended) ,JDK(8、11),Maven (3.0.4、later) | Java 8、HA(zookeeper)、checkpoints (HDFS / S3 / NFS / SAN / GFS / Kosmos / Ceph / …) | 81 | | | | 资源耗费量大 | 82 | | | | | 83 | 84 | -------------------------------------------------------------------------------- /mysql.md: -------------------------------------------------------------------------------- 1 | #### mysql 5.7 sql_mode 2 | 3 | 1、查看sql_mode 4 | 5 | ``` 6 | SELECT @@GLOBAL.sql_mode; 7 | SELECT @@SESSION.sql_mode; 8 | ``` 9 | 10 | 查询出来的值为: 11 | 12 | ``` 13 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 14 | ``` 15 | 16 | 2、去掉ONLY_FULL_GROUP_BY,重新设置值。 17 | 18 | ``` 19 | set @@GLOBAL.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; 20 | ``` 21 | 22 | 3、上面是改变了全局sql_mode,对于新建的数据库有效。对于已存在的数据库,则需要在对应的数据下执行: 23 | 24 | ``` 25 | set @@SESSION.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; 26 | 或者: 27 | ``` 28 | 29 | ``` 30 | 在my.cnf 里面设置 31 | sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' 32 | 在sql_mode 中去掉only_full_group_by 33 | ``` 34 | ---- 35 | 36 | ## 数据库安装和找回密码 37 | 38 | ### 1.配置 yum 源 39 | 去 MySQL 官网下载 YUM 的 RPM 安装包,http://dev.mysql.com/downloads/repo/yum/ 40 | 下载 mysql 源安装包 41 | > $ curl -LO http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 42 | 43 | 安装 mysql 源 44 | > $ sudo yum localinstall mysql57-community-release-el7-11.noarch.rpm 45 | 46 | 检查 yum 源是否安装成功 47 | > $ sudo yum repolist enabled | grep "mysql.*-community.*" 48 | mysql-connectors-community MySQL Connectors Community 21 49 | mysql-tools-community MySQL Tools Community 38 50 | mysql57-community MySQL 5.7 Community Server 130 51 | 52 | 如上所示,找到了 mysql 的安装包 53 | 54 | ### 2.安装 55 | $ sudo yum install mysql-community-server 56 | 57 | ### 3.启动 58 | 安装服务 59 | $ sudo systemctl enable mysqld 60 | 61 | 启动服务 62 | $ sudo systemctl start mysqld 63 | 64 | 查看服务状态 65 | $ sudo systemctl status mysqld 66 | 67 | ### 4.修改 root 默认密码 68 | MySQL 5.7 启动后,在 /var/log/mysqld.log 文件中给 root 生成了一个默认密码。通过下面的方式找到 root 默认密码,然后登录 mysql 进行修改: 69 | ``` 70 | $ grep 'temporary password' /var/log/mysqld.log 71 | [Note] A temporary password is generated for root@localhost: ********** 72 | ``` 73 | 74 | 登录 MySQL 并修改密码 75 | ``` 76 | $ mysql -u root -p 77 | Enter password: 78 | mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!'; 79 | ``` 80 | 注意:MySQL 5.7 默认安装了密码安全检查插件(validate_password),默认密码检查策略要求密码必须包含:大小写字母、数字和特殊符号,并且长度不能少于 8 位。 81 | 通过 MySQL 环境变量可以查看密码策略的相关信息: 82 | ``` 83 | mysql> SHOW VARIABLES LIKE 'validate_password%'; 84 | +--------------------------------------+--------+ 85 | | Variable_name | Value | 86 | +--------------------------------------+--------+ 87 | | validate_password_check_user_name | OFF | 88 | | validate_password_dictionary_file | | 89 | | validate_password_length | 8 | 90 | | validate_password_mixed_case_count | 1 | 91 | | validate_password_number_count | 1 | 92 | | validate_password_policy | MEDIUM | 93 | | validate_password_special_char_count | 1 | 94 | +--------------------------------------+--------+ 95 | 7 rows in set (0.01 sec) 96 | ``` 97 | 98 | 具体修改,参见 http://dev.mysql.com/doc/refman/5.7/en/validate-password-options-variables.html#sysvar_validate_password_policy 99 | 指定密码校验策略 100 | ``` 101 | $ sudo vi /etc/my.cnf 102 | 103 | [mysqld] 104 | ``` 105 | ###### 添加如下键值对, 0=LOW, 1=MEDIUM, 2=STRONG 106 | validate_password_policy=0 107 | 108 | 禁用密码策略 109 | ``` 110 | $ sudo vi /etc/my.cnf 111 | 112 | [mysqld] 113 | ``` 114 | ###### 禁用密码校验策略 115 | validate_password = off 116 | 117 | 重启 MySQL 服务,使配置生效 118 | $ sudo systemctl restart mysqld 119 | 120 | ### 5.添加远程登录用户 121 | MySQL 默认只允许 root 帐户在本地登录,如果要在其它机器上连接 MySQL,必须修改 root 允许远程连接,或者添加一个允许远程连接的帐户,为了安全起见,本例添加一个新的帐户: 122 | ``` 123 | mysql> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' IDENTIFIED BY 'secret' WITH GRANT OPTION; 124 | ``` 125 | ### 6.配置默认编码为 utf8 126 | MySQL 默认为 latin1, 一般修改为 UTF-8 127 | $ vi /etc/my.cnf 128 | [mysqld] 129 | ###### 在myslqd下添加如下键值对 130 | ``` 131 | character_set_server=utf8 132 | init_connect='SET NAMES utf8' 133 | ``` 134 | 重启 MySQL 服务,使配置生效 135 | ``` 136 | $ sudo systemctl restart mysqld 137 | ``` 138 | 查看字符集 139 | 140 | mysql> SHOW VARIABLES LIKE 'character%'; 141 | ``` 142 | +--------------------------+----------------------------+ 143 | | Variable_name | Value | 144 | +--------------------------+----------------------------+ 145 | | character_set_client | utf8 | 146 | | character_set_connection | utf8 | 147 | | character_set_database | utf8 | 148 | | character_set_filesystem | binary | 149 | | character_set_results | utf8 | 150 | | character_set_server | utf8 | 151 | | character_set_system | utf8 | 152 | | character_sets_dir | /usr/share/mysql/charsets/ | 153 | +--------------------------+----------------------------+ 154 | 8 rows in set (0.00 sec 155 | ``` 156 | 157 | ### 7.开启端口 158 | ``` 159 | $ sudo firewall-cmd --zone=public --add-port=3306/tcp --permanent 160 | $ sudo firewall-cmd --reload 161 | ``` 162 | 163 | 164 | --- 165 | ##### 查询用户权限 166 | ``` 167 | SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user; 168 | ``` 169 | 170 | ##### 将数据库授权 171 | 172 | ``` 173 | grant rights on database.* to user@host identified by "pass"; 174 | ``` 175 | 176 | 177 | This is the set root password that you will perform inside mysql if you have MySQL 5.6 or below: 178 | 179 | mysql> update user set Password=PASSWORD('new-password') where user='root'; 180 | flush privileges; 181 | In MySQL 5.7 or above 182 | 183 | mysql> update user set authentication_string=PASSWORD('new-password') where user='root'; 184 | flush privileges; 185 | -------------------------------------------------------------------------------- /Middleware.md: -------------------------------------------------------------------------------- 1 | ## 1. 中间件定义 2 | 3 | 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。 4 | 5 | 6 | 中间件是一类连接软件组件和应用的计算机软件,它包括一组服务。以便于运行在一台或多台机器上的多个软件通过网络进行交互。该技术所提供的互操作性,推动了一致分布式体系架构的演进,该架构通常用于支持并简化那些复杂的分布式应用程序,它包括web服务器、事务监控器和消息队列软件。 7 | 8 | --- 9 | 也许很难给中间件一个严格的定义,但中间件应具有如下一些特点: 10 | > 1. 满足大量应用的需要; 11 | > 2. 运行于多种硬件和OS平台,支持分布计算,提供跨网络、硬件和OS平台的透明性的应用或服务的交互; 12 | > 3. 支持标准的协议和接口; 13 | --- 14 | 15 | ### 2. 技术现状 16 | 中间件技术服务复杂网络应用的共性问题中不断发展和壮大起来的,可以归纳为下面几个方面: 17 | 18 | 1、从计算环境来看:中间件面对的是一个复杂、不断变化的计算环境,要求中间件技术具有足够的灵活性和可成长性; 19 | 20 | 2、从资源管理的角度来看:操作系统和数据库管理系统管理的是有限资源,资源种类有限,资源量也有限,而中间件需要管理的资源类型(数据、服务、应用)更丰富,且资源扩展的边界是发散的; 21 | 22 | 3、从应用支撑角度来看:中间件需要提供分布应用开发、集成、部署和运行管理的整个生命周期的总体运行模型,随着分布式商业或者数字商业的发展,需要进一步变革传统的方式; 23 | 24 | 4、从应用的角度来看:利用中间件完成的往往是复杂、大范围的企业级应用,其关系错综复杂,流程交织。例如客户关系管理系统需要集成多个企业内部应用,而供应链管理则涉及企业之间的应用集成。 25 | 26 | 27 | 因此,由于网络应用的复杂性,特别是分布、异构和自治等特点,决定了中间件技术和产品的形态多样性。但是随着时间的变化。中间件技术已经形成一个丰富的体系,并正在向上(应用框架和普适服务)和向下(融合操作系统、数据库管理系统的功能)两个方向不断延伸,并在向更宽广的应用领域拓展。 28 | 29 | 30 | --- 31 | ### 3. 供应商层面 32 | 33 | 34 | 35 | 36 | --- 37 | ### 4. 分类 38 | 39 | 中间件分类(IDC的分类):数据访问中间件、远程过程调用中间件、消息中间件、交易中间件、对象中间件。 40 | 41 | 42 | #### 4.1 分布环境下的通讯服务,我们将这种通讯服务称之为平台。 43 | 44 | 基于目的和实现机制的不同,我们将平台分为以下主要几类: 45 | 远程过程调用中间件(Remote Procedure Call) 46 | 面向消息的中间件(MesSAge-Oriented Middleware) 47 | 对象请求代理中间件(object RequeST Brokers) 48 | 49 | --- 50 | 51 | ## 5. 趋势特征 52 | 53 | 中间件技术的发展方向,将聚焦于消除信息孤岛,推动无边界信息流,支撑开放、动态、多变的互联网环境中的复杂应用系统,实现对分布于互联网之上的各种自治信息资源(计算资源、数据资源、服务资源、软件资源)的简单、标准、快速、灵活、可信、高效能及低成本的集成、协同和综合利用,提高组织的IT基础设施的业务敏捷性,降低总体运维成本,促进IT与业务之间的匹配。中间件技术正在呈现出业务化、服务化、一体化、虚拟化等诸多新的重要发展趋势。 54 | 55 | 56 | ### 5.1 分布式消息中间件 57 | 58 | “Message-oriented middleware (MOM) is software or hardware infrastructure supporting sending and receiving messages between distributed systems.”——维基百科 59 | 60 | 那么分布式消息中间件其实就是指消息中间件本身也是一个分布式系统。 61 | 62 | 消息中间件的应用场景大致如下: 63 | 64 | 业务解耦:交易系统不需要知道短信通知服务的存在,只需要发布消息 65 | 66 | **削峰填谷**:比如上游系统的吞吐能力高于下游系统,在流量洪峰时可能会冲垮下游系统,消息中间件可以在峰值时堆积消息,而在峰值过去后下游系统慢慢消费消息解决流量洪峰的问题 67 | 68 | **事件驱动**:系统与系统之间可以通过消息传递的形式驱动业务,以流式的模型处理 69 | 70 | 71 | --- 72 | 73 | ### 5.2 架构可视化 74 | 75 | 核心点是有意义和有效,要做到这两点,首先需要识别什么是有意义和有效的元素和关系,我们在此领域做的事情归纳起来就是“识别”,识别机器上的每个进程是什么,发生的网络调用远端是什么,唯有知晓了这些元素是什么我们才有理由和依据来判断是否对用户有意义以及其在用户架构中的重要程度。 76 | 77 | #### 元素识别 78 | > - 自己的应用服务; 79 | > - 应用对外部的资源依赖; 80 | > - 服务器本身的信息。 81 | 82 | 应用对外部资源的依赖通常以其它应用和通用中间件或者存储服务两种形式存在。故我们将需要识别的进程分为:应用服务和常见的组件服务(比如Redis、MySQL等),这些组件服务又分为用户自建的服务和使用公有云提供的服务,特别是对于Cloud Native应用来说,云服务的识别显得格外重要。 83 | 84 | ### 5.3 还可以做什么 85 | 86 | > 借助架构感知采集到的架构数据,在识别了用户使用的组件(我们对MySQL、Redis、MQ等的统称)后,我们借助这些组件以及与组件匹配的故障库,可以给用户自动推荐这些组件可能遇到的故障,配合我们提供的评测服务让用户更方便地对组件进行各种故障的模拟与演练,以提高系统的健壮性。 87 | 88 | [体验产品](https://www.aliyun.com/product/ahas) 89 | 90 | --- 91 | ### 公司维度 92 | #### 1. TIBCO 93 | ##### Spotfire 94 | 95 | All-new A(X) Experience 96 | Analytics, Accelerated 97 | 98 | ``` 99 | The all-new TIBCO Spotfire® A(X) Experience makes it fast and easy for everyone to get value out of data —whether you’re just getting started with analytics or an expert trying to uncover deeper insights. 100 | ``` 101 | 102 | ##### jaspersoft 103 | 104 | 105 | Data visualization and reporting in a world of cloud, microservices, and DevOps 106 | 107 | 108 | 109 | #### 2. mulesoft 110 | **Connect anything. Change everything** 111 | 112 | Build an application network with secure, reusable integrations and APIs designed, built, and managed on Anypoint Platform™. 113 | 114 | 115 | #### 3. apigee 116 | 117 | API管理 118 | The Cross-Cloud API Management Platform 119 | 120 | 121 | #### 4. Informatica 122 | 在Informatica看来,数据治理包含探查、定义、应用和衡量与监控四方面。数据治理的前提就是要先了解治理,知道治理的目标、治理的主体,探讨分析是数据治理的第一步。其次,将非标准化的东西统一成标准化,制定业务词汇表、业务规则与规定等,对相关内容进行定义标准。第三是应用,制定自动化规则以及确定手动工作流程。最后就是衡量,取决于治理的结果和定义目标达成的情况,然后决定下一步计划。 123 | 124 | #### 5. Nastel 125 | 126 | 中间件管理 127 | 128 | Nastel Technologies’ product family is called AutoPilot. AutoPilot is software for real-time monitoring of the availability and performance of business applications. Using complex event processing and business transaction management it provides real-time visibility of applications, middleware and transactions, as well as predictive alerting. 129 | 130 | Nastel AutoPilot has been especially effective in the banking industry[4] and in insurance, healthcare and retail. 131 | 132 | ##### 5.1 Middleware Monitoring & Management 133 | 134 | 135 | Use the solution employed by the world’s largest middleware environments to ensure the performance and reliability of business-critical enterprise applications. 136 | 137 | ##### 5.2 Transaction Tracking,Business Tracking 138 | 139 | 140 | Understand how transaction performance affects your business processes. Nastel tracks and troubleshoots end-to-end business transactions in real-time, from mobile to applications, middleware, brokers, and mainframe. 141 | 142 | ![image](https://www.nastel.com/wp-content/uploads/Nastel-Infrastructure-graphic-1100.jpg) 143 | 144 | 145 | #### 6. 阿里云中间件 146 | 阿里中间件的范围分为: 147 | 148 | ``` 149 | 基础中间件 150 | 运维平台 151 | 稳定性相关平台 152 | 云产品服务 153 | 计算平台 154 | 存储平台 155 | ``` 156 | 157 | 158 | ![image](https://blog-100offer.100offer.com/p/f9ca954149414ae8a0a09c6ed7214d931490884646) 159 | 160 | 161 | 162 | 往上就是存储层、数据库相关的,包括缓存 Tair、文件系统相关的 TFS、我们的框表 HBase、面向海量数据分析型的列式数据库 HiStore 以及面向于时间序列相关的 HiTSDB,还承接阿里巴巴整个交易平台过程中需要的关系型数据库 MySQL 和金融场景相关的 OceanBase。 163 | 164 | 再往上是应用层的运行容器,包括 Linux 和 Tomcat。 165 | 166 | 在往上,属于分布式的数据层,就是如何把海量数据进行分库分表,围绕这些数据库进行数据迁移。 167 | 168 | 再往上是整个的消息中间件,包括事务消息、顺序消息的中间件 Notify 和 Metaq。还有我们在集团中广泛应用的服务框架 HSF。 169 | 170 | 在向上,就是整个阿里巴巴应用的接入层了,包括 Tengine、LVS。 171 | 172 | 从图上再向右看去,我们会看到实时计算平台 JStorm 和之前提到过的分布式日志系统 EagleEye、TLog 和所有服务器上都在部署的日志收集器。 173 | 174 | 再向右,是资源管理/调度弹性/容器化系统。 175 | 176 | 整个左半部分,由中间件的这些技术,承接着所有的业务产品,包括淘宝、天猫、1688、AE、B2B以及圈子收购的子公司优酷、高德等等。我们将所有这些技术经验沉淀出了产品,并在云上形成服务。目前已经形成云产品的包括,EDAS、DRDS、MQ、TXC,以及面向监控的 ARMS 和时间分片的 SchedulerX,以及围绕这些服务的云产品中台。 177 | 178 | 179 | 180 | 181 | --- 182 | 还需要研究的公司 183 | - tx 184 | - 微软 185 | - [tervela](http://www.tervela.com/products/data-fabric/) 186 | - [mulesoft](https://www.mulesoft.com/cn/) 187 | 188 | 189 | 190 | 191 | --- 192 | 数据提供公司 193 | - [crunchbase](https://www.crunchbase.com/organization/tervela#section-overview) 194 | 195 | 196 | --- 197 | 相关报告 198 | - [The Forrester Wave™: API Management Solutions, Q4 2018](https://reprints.forrester.com/#/assets/2/157/RES141540/reports) 199 | 200 | -------------------------------------------------------------------------------- /坐而论道_我也跟着说说FRP_FP.md: -------------------------------------------------------------------------------- 1 | # 背景 2 | 主要是针对 [FRP && FP](讲讲FRP_FP.md) 说一下个人看法. 3 | 4 | 这篇文章里从内容上来看,有`范式` ,`编程范式`,`计算机模型分析`,`FRP`,` FP`,`命令式编程 && 函数式编程`,`JS中一些实例`,`闭包,纯函数,高阶函数`等等. 平心而论,虽然题目是`讲讲FRP_FP`,但内容里FRP讲的少. 5 | 我半路出家,学艺不精,看完还是没明白啥是FRP. 6 | 7 | 在具体针对各个观点讨论前,我先得介绍一下我自己.要不然很容易引起误会. 8 | 我大学不是计算机专业,学地理的我.非科班出身,做计算机完全是兴趣加实用. 9 | 喜欢这东西,有趣,我就愿意多折腾. 毕业的时候,它顺带能给我找份工作,糊个口.别人花钱雇我去做我喜欢做的事情. 10 | 这是很开心的事.至于其他的,没过多做计较.南来北往的,去过正规的IT公司,也去过毫无IT味道可言的企业. 11 | 总之,入这行的经历及初心,让我不太一样. 而且直到现在,我内心也不认同程序员或者码农这个称号. 我不认为我属于这个群体. 12 | 我觉得我写代码的时候,是在写作,或者对话,是有趣的事情. 13 | IT从业者都是人,是人的地方就是江湖. 有江湖就有门派. 科班与草根. 我毫无疑问,草根一族了. 草根大都自学成才的. 他们一般有他们自己的理念与方法. 我也一样. 我可以分享一下我的的理念及方法.简单主义(注意,是简单不是极简,没有这个极字),实用主义.简而言之,就是没有品味没有追求的能用就好. 14 | 梅芬梅小姐不出意外应是科班出身. 比起正宗CS的博大精深,我的这些个人三脚猫,自然是难登大雅之堂,入不得厅门. 15 | 但如果你想真正理解明白我说的内容,最好先空杯,忘掉头脑中CS的种种,就像倚天屠龙记里张三丰给张无忌教太极拳太极剑一样. 16 | 忘完所有,然后你看我说的对不对,对的你吸收,不对的你丢弃即可. 17 | 18 | 1. 编程范式 19 | 程序是现实世界的抽象. 所谓`编程范式`,说白了就是你怎么看待理解这个世界,然后以程序的语言表述出来. 20 | 如果在你的眼里,世界里所有的一切都是`函数`,所有的活动,都可以通过`函数调用`来完成,那你就是函数式了. 21 | 如果你理解世界的方式是基于`方以类聚,物以群分`,那面向对象这种很适合你. 22 | 如果你理解世界的方式是比较悲观的,`冥冥之中,自有天意`,人生每一步都是老天安排好的. 那指令式,面向过程这种就很适合你. 23 | 但是,世界是非常复杂的. 所有的范式难免盲人摸象的感觉.只得一角,不见全图. 窥一斑而知全豹这种情况在我看来是不存在的. 24 | 所以,我个人比较推崇混合范式编程. 像Scala,Julia这种语言,它不做限制. 至于你在写代码的时候,到底运用了哪套范式,我不在乎的. 25 | 我建议是根据具体场景,具体问题具体分析. 尺有所短寸有所长. 在合适的地方用适合的东西. 在都合适的地方用熟悉的东西. 26 | 当然,这会导致一个结果. 就是乍一看,你的代码乱七八糟.一会儿FP一会儿OO的.这个是代价,需要自己判断做取舍. 27 | 28 | 2. 计算模型分析 29 | 所谓计算模型,就是回答一个问题,计算机怎么做计算? 30 | 回答这个问题前,得先说明白,什么是计算机. 计算机就是用来做计算的机器. 31 | 那又抛出一个问题,什么是计算? 也就是计算的本质到底是什么. 32 | 关于计算的本质,目前我个人了解到的有两个答案. 33 | 一个是图灵的回答. 一个是邱奇的回答. 34 | 图灵的答案是这样的. 计算呢,就是计和算. 计,就是存储.(把东西记下来嘛) 算,就是运算.(算一下1+1等于几). 35 | 最简单的符合冯诺依曼体系的计算机,是"结绳记事". 给我一根绳子,我就成了计算机. 这里面有IO系统,(眼睛),有控制系统(手),有CPU和内存(绳). 怎么理解呢? 打一个结,就是存储一. 打两个结就是存储二. 它可以存储. 同理,我要做一次加法,我多打一个结. 我要做一次减法,我拆掉一个结. 所以,计就是算,算就是计.CPU里面全是寄存器. 所谓算法里的时间换空间或空间换时间.其实也是源于此. 36 | 那从图灵这种套路出发, 计算机怎么做计算这个问题,答案大概就是这样的了. 计算机通过存储+控制,(也可以说数据结构+算法),通过操作指令来更新数据实现计算. 37 | 38 | 邱奇的答案是这样的. 邱奇是逻辑学家. 逻辑学家没有计算的概念的,他们有自己的语言,他们不讲这一套. 39 | 逻辑学是刨根问底儿的学问. 逻辑的基石必须稳固. 不然最后的结论很可能就错了. 40 | 逻辑学有一些发展阶段,什么论证逻辑(比如命题啊,归纳演绎啊),到后面有形式逻辑,符号逻辑. 这方面我根本不懂. 41 | 但是有两点我比较清楚. 42 | 一, 布尔代数或者集合论这些数学工具可以跟逻辑学里面的那些规则及运算建立映射关系. 从而,研究数学就等于研究逻辑学,研究逻辑学也等同于研究数学. 43 | 二,lambda演算可以拿来计算 44 | 第一点不多说,说说第二点. 45 | 所有的逻辑都需要一个基石. lambda演算的基石就是lambda表达式. 46 | 一个lambda表达式是一个只有一个参数的匿名函数.比如 (x)=>x 47 | 只有一个参数,那多不好玩. 所以就有了柯里化. 48 | 柯里化是这样的 , 49 | 比如一个加法lambda (x,y)=> (y)=> x +y 50 | 可以试一下JS中调用 51 | ``` 52 | // 1 + 2 53 | ((x,y)=> (y)=> x +y ) (1)(2) 54 | // 3 55 | ``` 56 | 或者一个 select second lambda (first,second)=> (second)=> second 57 | ``` 58 | // select_second ('hello',' world') 59 | ((first,second)=> (second)=> second) ('hello')('world') 60 | // "world" 61 | ``` 62 | 63 | 总之, 柯里化其实是个语法糖,它可以使我们用单参函数,来表示多参函数. 64 | 这种思想非常重要,多的是通过单的通过某种手法呈现出来的. 65 | 66 | 紧接着说说`高阶函数` 67 | 在lambda演示里,`高阶函数`是很自然的东西. 因为它的基石只有lambda表达式,也就是匿名函数. 68 | 一个返回函数的函数就是高阶函数. 比如柯里化后的多参函数就是高阶函数. 69 | 在上面的JS示例中,我们的参数有1,2,'hello','world'. 但目前,这些东西是没有的.我们的定义域内,只有一个东西,就是lambda表达式. 70 | 71 | 但是这些东西其实是可以定义出来的. 72 | 一个非常有趣的例子就是,邱奇数. 具体理论上的我不说,我也不会. 我简单说一下,主要是有三个东西. 73 | 一个起点(也就是零),一个前进函数(也叫前继),一个后退函数(也叫后继). 总之,相关理论可以参看,自然数公理化. 74 | 什么意思呢? 75 | 0是预定义的. 前进和后退也是预定义的. 要想得到1,0前进一步得到的结果就是1. 76 | 在lambda里面这样表示: 77 | 78 | zero=(x)=>x 79 | forward=(x)=>()=>x 80 | backward=(x)=>x() 81 | // 一般叫SUCC函数.. 82 | 可以验证一下 83 | ``` 84 | var one=forward(zero) 85 | var two=forward(one) 86 | 87 | console.log(backward(two)===one) // true 88 | console.log(backward(one)===zero) //true 89 | ``` 90 | 总之,大意如此. 91 | 自然数是可以通过lambda演算来定义的. 92 | 有了数之后,紧接着是加法. 为什么是加法? 因为减法是可以由加法定义的,乘法也是可以由加法定义的. 93 | ``` 94 | add(a, b){ 95 | if(a===zero){ 96 | retrun b 97 | } 98 | else{ 99 | return add(backward(a),forward(b)) 100 | } 101 | } 102 | ``` 103 | 什么意思呢? 加法是被定义的. 两条规则,1. 0和任何数的加法是对应的数. 2. 如果这个数非零,那就等于a的后退加b的前进. 104 | 比如 2+3,2非零,就等于1+4. 1非零,就等于0+5. 0加任何数等于对应的数,那么就返回5. 105 | 106 | 在这里我们要注意. 加法运算是通过公理化的定义实现的. 而不是之前"多打个结"这种存储的方式实现. 107 | 这是我感觉邱奇的答案最美妙的地方.优雅的很. 108 | 109 | 上面的例子中,引用到了几个没有定义的东西, 一个是递归调用add,另一个是 if else 逻辑判断. 110 | 下面说说 用lambda来定义布尔运算,也就是逻辑判断. 最后再构造if else. 111 | 一般编程里 0,1表示true ,false. 这里我们也可以借鉴. 此次不借鉴,我举个其他书上的例子. 112 | T =(first)=>(second)=>first 113 | F =(first)=>(second)=>second 114 | IF =(x)=>x 115 | 这里我定义了true 和 false 和if 116 | 可以看一眼执行结果.符合预期. 117 | ``` 118 | IF(T)(1)(2) 119 | // 1 120 | IF(F)(1)(2) 121 | //2 122 | ``` 123 | 顺带我定义一个逻辑操作符 AND 124 | 这里可以根据真值表来构造AND函数, true and ture = true ,true and false = false ,false and true = false,false and false =false. 这里可以看到,只有第一种情况返回true,其他情况直接返回false. 125 | 那么我的 and 可以这样定义. 126 | ``` 127 | and=(p)=>(q)=>IF(p)(IF(q)(T)(F))(F) 128 | // 验证一下 129 | and(T)(T)==T //true 130 | and(T)(F)==F //true 131 | ``` 132 | 其他的not or 以此类推. 133 | 134 | 下面需要说说递归调用add这个怎么处理. 135 | lambda表达式是匿名函数.我们这里所有的东西目前而言,没有说到怎么定义一个有名的表达式. 136 | 比如刚刚提到的 zero=(x)=>x . 这里我们直接使用了=来定义,但并没有说怎么使用lambda来定义这个=. 137 | 这个后面再说. 目前说一下,匿名函数怎么递归. 递归就是自己调用自己. 138 | 有名的好理解. 比如阶乘函数 139 | ``` 140 | factorial=(n)=>{ 141 | if(n===1){return 1} 142 | return n*factorial(n-1) 143 | } 144 | 145 | ``` 146 | 这里面 求n的阶乘的时候,用到了n-1的阶乘. 147 | 148 | 在lambda里面有个函数叫y组合子,当然也有其他组合子. 数学上叫不动点.相关的有不动点定理. 149 | 这是个啥玩意? 150 | 举个例子, 你有一张上海市地图,拿了根针,从地图上随便扎过去.钉到地上. 151 | 不动点定理是说,你肯定能找到一个点,地图上扎的点和钉到地上的点是同一个地方. 而你找到的这个点就是个不动点. 152 | 数学上呢,f(x)=x,满足这个关系的就是不动点. 153 | 154 | Y组合子呢就是个不动点方程,这个方程里所有的点都是不动点. 就像一扇神奇的门,你推开门进去后发现,对面推门而入的那个人是你自己. 155 | 156 | Y = λf.(λx.f (x x)) (λx.f (x x)) 157 | 这是它的定义,关于它的推导过程,我也不会啊.但是,不影响直接拿来用. 158 | ``` 159 | // λf. (λx. f (λy. x x y)) (λx. f (λy. x x y)) 160 | 161 | const Y = f => 162 | (x => f(y => x(x)(y))) 163 | (x => f(y => x(x)(y))) 164 | 165 | // 调用 166 | Y(myself=>n=>n==1?1:n*myself(n-1)) (5) 167 | // 120 168 | ``` 169 | 总之,很神奇啦. 至于这个不动点是怎么传来传去,又调用到自己的.我是想不明白. 也不多想了. 170 | 但是有一点可以断定,不动点是联系两个空间的点.想象一下上海地图和上海.在那个不动点处,它同时在两个空间里有相同的表现. 171 | 这让我思考.或许我可以和另一个空间沟通,只要某种条件下我能成为两个空间的不动点. 这个条件,也就是这个函数,可以想象,肯定非常有趣. 172 | 比如未来的我是一个空间,现在的我处于一个空间. 如果有个"针","穿透地图,落到地上,砸到我身上",我成为两个空间的不动点. 173 | 想象不来会有什么情况发生. 174 | 关于递归就这么多吧. 175 | 至于闭包,是为了消除lambda表达式中外部变量引用. 纯函数嘛,纯不纯看有没有副作用. 另外还有幂等性,引用透明性等概念也没讨论. 176 | lambda演算部分就此别过. 177 | 178 | 下面说说函数式编程. 179 | lambda表达式在一些语言里对应着一个匿名函数. 但是匿名函数又不是lambda表达式,因为lambda表达式是单参的. 180 | 这里不做深究,没意义,迷迷糊糊地用就行. 181 | 函数式编程,有很多概念和定义.这里我只说我的几点倾向. 182 | 1. 函数需是一等公民,鼓励纯函数 183 | 2. 数据流主导控制流 184 | 3. 使用不可变数据 185 | 186 | 这里必须得说说LISP, 这个我认为虽然它常常和函数式编程联系在一起,但它和函数式编程本质上不同. 187 | 因为LISP里面最根本的元素不是函数,而是list(列表). 它这个列表的特殊之处是,如果它的列表头,就是第一项是一个符合,它会找这个符合的定义,去把它当函数来执行,参数是列表的剩余项. 188 | 这也是LISP为什么称自己"代码既数据,数据既代码". 189 | 它可以理解为纯数据流. 190 | 它们的关系是 list是最根本的,基于list的特例(也就是第一个元素是符号), 把这个列表转换为一个函数, 191 | 在LISP里,函数其实是二级公民. 虽然一级公民的list很庞大,但是纯静态的列表, 192 | 计算的能力太弱了(感觉可能没有,但是我也不能确定,一堆静态的列表数据能不能计算).所以,二级公民俨然一级公民了. 193 | 194 | 呃,还没谈到FRP...但我已经饿晕了快.后面再补充吧.. 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /java.md: -------------------------------------------------------------------------------- 1 | ## 1. 拦截器的使用 2 | 3 | - [在springBoot 2里添加拦截器](https://blog.csdn.net/qq_36013216/article/details/79866114) 4 | 5 | ## 说明 6 | ``` 7 | /* 8 | @Configuration //指明该类为Spring 配置类 9 | @Component //泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 10 | @EnableWebSocket //声明该类支持WebSocket 11 | /* 12 | 13 | @Configuration 14 | @EnableWebSocket 15 | @Component 16 | @Slf4j 17 | public class StompConfig implements WebSocketConfigurer { 18 | 19 | @Override 20 | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 21 | registry.addHandler(new BrokerStomp(), "/test").addInterceptors(intercept()).setAllowedOrigins("*").withSockJS(); 22 | } 23 | 24 | @Bean 25 | public HandShakeWebSocketInterceptor intercept() { 26 | HandShakeWebSocketInterceptor intercept = new HandShakeWebSocketInterceptor(); 27 | return intercept; 28 | } 29 | } 30 | 31 | ``` 32 | 33 | ``` 34 | public class HandShakeInterceptor implements HandshakeInterceptor { 35 | 36 | @Override 37 | public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 38 | Map attributes) throws Exception { 39 | 40 | if (request instanceof ServletServerHttpRequest) { 41 | ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; 42 | HttpSession session = servletRequest.getServletRequest().getSession(false); 43 | //TODO: 44 | } 45 | return true; 46 | } 47 | 48 | @Override 49 | public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 50 | Exception exception) { 51 | // TODO 52 | 53 | } 54 | } 55 | ``` 56 | --- 57 | ## 2. Spring AOP注解失效及解决 58 | 基于以上对于动态代理原理的分析,我们来看以下两个常见的问题: 59 | 60 | ### 同一个类中,方法A调用方法B(方法B上加有注解),注解无效 61 | 62 | 针对所有的Spring AOP注解,Spring在扫描bean的时候如果发现有此类注解,那么会动态构造一个代理对象。 63 | 64 | 如果你想要通过类X的对象直接调用其中带注解的A方法,此注解是有效的。因为此时,Spring会判断你将要调用的方法上存在AOP注解,那么会使用类X的代理对象调用A方法。 65 | 66 | 但是假设类X中的A方法会调用带注解的B方法,而你依然想要通过类X对象调用A方法,那么B方法上的注解是无效的。因为此时Spring判断你调用的A并无注解,所以使用的还是原对象而非代理对象。接下来A再调用B时,在原对象内B方法的注解当然无效了。 67 | 68 | #### 解决方法: 69 | 70 | 最简单的方式当然是可以让方法A和B没有依赖,能够直接通过类X的对象调用B方法。 71 | 72 | 但是很多时候可能我们的逻辑拆成这样写并不好,那么就还有一种方法:想办法手动拿到代理对象。 73 | 74 | AopContext类有一个currentProxy()方法,能够直接拿到当前类的代理对象。那么以上的例子,就可以这样解决: 75 | ``` 76 | // 在A方法内部调用B方法 77 | // 1.直接调用B,注解失效。 78 | B() 79 | // 2.拿到代理类对象,再调用B。 80 | ((X)AopContext.currentProxy()).B() 81 | AOP注解方法里使用@Autowired对象为null 82 | ``` 83 | 84 | 在之前的使用中,出现过在加上注解的方法中,使用其他注入的对象时,发现对象并没有被注入进来,为null。 85 | 86 | 最终发现,导致这种情况的原因是因为方法为private。因为Spring不管使用的是JDK动态代理还是CGLIB动态代理,一个是针对实现接口的类,一个是通过子类实现。无论是接口还是父类,显然都不能出现private方法,否则子类或实现类都不能覆盖到。 87 | 88 | 如果方法为private,那么在代理过程中,根本找不到这个方法,引起代理对象创建出现问题,也导致了有的对象没有注入进去。 89 | 90 | 所以如果方法需要使用AOP注解,请把它设置为非private方法。 91 | 92 | ##### EXAMPLE 93 | ``` 94 | @SpringBootApplication 95 | public class Application { 96 | 97 | @Autowired 98 | BookingService bookingService; 99 | 100 | public static void main(String[] args) { 101 | bookingService.book("Alice", "Bob", "Carol"); 102 | } 103 | } 104 | 但可以使用@Bean 105 | 106 | @SpringBootApplication 107 | public class Application { 108 | 109 | @Bean 110 | BookingService bookingService() { 111 | return new BookingService(); 112 | } 113 | 114 | public static void main(String[] args) { 115 | ApplicationContext context = SpringApplication.run(Application.class, args); 116 | BookingService bookingService = context.getBean(BookingService.class); 117 | bookingService.book("1", "2", "3"); 118 | } 119 | } 120 | ``` 121 | ##### 解释说明 122 | 简而言之:new出来的对象,脱离了Spring的容器 123 | 124 | - IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象,是通过DI(Dependency Injection,依赖注入)来实现的。 125 | - 创建合作对象B的工作是由Spring来做的,Spring创建好B对象,然后存储到一个容器里面,当A对象需要使用B对象时,Spring就从存放对象的那个容器里面取出A要使用的那个B对象,然后交给A对象使用,至于Spring是如何创建那个对象,以及什么时候创建好对象的,A对象不需要关心这些细节问题(你是什么时候生的,怎么生出来的我可不关心,能帮我干活就行),A得到Spring给我们的对象之后,两个人一起协作完成要完成的工作即可。 126 | - 控制反转IoC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IoC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。 127 | 128 | ### 3. 内部类持有外部类的引用,获取Java匿名内部类持有的外部类对象 129 | 130 | ``` 131 | class Outer { 132 | static class Inner { 133 | public String publicString = "Inner.publicString"; 134 | } 135 | 136 | static Other anonymousOther = new Other() { 137 | public String publicString = "Anonymous Other.publicString"; 138 | }; 139 | 140 | public Other getAnonymousOther() { 141 | return anonymousOther; 142 | } 143 | 144 | Other Other = new Other(); 145 | public Other getOther() { 146 | return Other; 147 | } 148 | } 149 | 150 | class Other { 151 | public String publicString = "Other.publicString"; 152 | } 153 | 154 | 155 | public static void main(String args[]) { 156 | printField(new Outer.Inner()); 157 | System.out.println("\t"); 158 | printField(new Outer().getAnonymousOther()); 159 | System.out.println("\t"); 160 | printField(new Outer().getOther()); 161 | } 162 | ``` 163 | 164 | 第二部分 165 | ``` 166 | public interface Callback { 167 | void callback(String s); 168 | } 169 | 170 | 171 | public class Main { 172 | 173 | private String mName; 174 | 175 | public Main(String name) { 176 | mName = name; 177 | } 178 | 179 | public static void main(String[] args) { 180 | Main main = new Main("Main"); 181 | main.test(); 182 | } 183 | 184 | private void test() { 185 | Callback callback = new Callback() { 186 | 187 | @Override 188 | public void callback(String s) { 189 | System.out.println(getName()); 190 | } 191 | }; 192 | callback.callback(""); 193 | } 194 | 195 | private String getName() { 196 | return mName; 197 | } 198 | } 199 | ``` 200 | ### 4. java异常 201 | 1、EOFException 202 | 203 | 抛出此类异常,表示连接丢失,也就是说网络连接的另一端非正常关闭连接(可能是主机断电、网线出现故障等导致) 204 | 205 | 206 | 207 | 2、ConnectException:connection refused connect. 208 | 209 | 抛出此类异常,表示无法连接,也就是说当前主机不存在 210 | 211 | 212 | 213 | 3、SocketException:socket is closed. 214 | 215 | 抛出此类异常,表示连接正常关闭,也就是说另一端主动关闭连接 216 | 217 | 218 | 219 | 4、SocketException:connection reset. 220 | 221 | 抛出此类异常,表示一端关闭连接,而另一端此时在读数据 222 | 223 | 224 | 225 | 5、SocketException:connect reset by peer. 226 | 227 | 抛出此类异常,表示一端关闭连接,而另一端此时在发送数据 228 | 229 | 230 | 231 | 6、SocketException:broken pipe. 232 | 233 | 抛出此类异常,表示连接已关闭,但还继续使用(也就是读/写操作)此连接 234 | 235 | 236 | 237 | 7、BindException:address already in use 238 | 239 | 抛出此类异常,表示端口已经被占用 240 | 241 | 242 | ### 5. 遍历Map 243 | 遍历Map时用到了Map.Entry 和 Map.entrySet() ,记得只见过Map.KeySet()和values()这两个方法,于是到API中一看,Map.entrySet() 这个方法返回的是一个Set>,Map.Entry 是一个接口,他的用途是表示一个映射项(里面有Key和Value),而Set>表示一个映射项的Set。Map.Entry里有相应的getKey和getValue方法. 244 | ``` 245 | for(Map.Entry item : m.entrySet()) { 246 | 247 | t.append(item.getKey() + ": " + item.getValue() + "/n"); 248 | 249 | } 250 | 251 | ``` 252 | -------------------------------------------------------------------------------- /讲讲FRP_FP.md: -------------------------------------------------------------------------------- 1 | # FRP && FP 2 | 3 | ## 1. Meta-Thinking 4 | ### 1.1 什么是范式(oriented)呢? 5 | > 所谓编程范式:指的是计算机编程的一种基本风格和典范格式。借用哲学的术语,如果说每一个编程者都去创造虚拟世界,那么编程范式就是他们置身其中自觉不自觉采用的世界观和方法论 6 | 7 | #### 编程范式 8 | 托马斯.库恩提出“科学的革命”的范式论之后,Robert Floyd在1979年图灵奖的颁奖演说中使用了编程范式一词。编程范式一般包括三个方面,以OOP为例: 9 | 1. 学科的逻辑体系——规则范式:如类/对象、继承、动态绑定、方法改写、对象替换等等机制。 10 | 2. 心理认知因素——心理范式:按照面向对象编程之父Alan Kay的观点,“计算就是模拟”。OO范式极其重视隐喻(metaphor)的价值,通过拟人化,按照自然的方式模拟自然。 11 | 3. 自然观/世界观——观念范式:强调程序的组织技术,视程序为松散耦合的对象/类的集合,以继承机制将类组织成一个层次结构,把程序运行视为相互服务的对象们之间的对话。 12 | ![image](http://vipkshttp0.wiz.cn/ks/share/resources/ac553236-ddd2-46ef-87ff-06ffbdb7863c/4260bd49-b50a-4785-a79f-1efc653487ac/index_files/6ca1c79a-b51b-484f-a283-10d6c106e4bd.png) 13 | 14 | #### 计算机模型分析 15 | 1. 基于图灵机(Turing Machine)的命令式编程 (Imperative Programming) 16 | 2. 基于图灵机(Turing Machine)的面向对象 Object-oriented Programming 17 | 3. 基于lamada-caculate(lamada的演算)函数式编程functional Programming 18 | 4. 基于First-order login(一阶逻辑)的逻辑编程范式 19 | 20 | ![image](http://vipkshttp0.wiz.cn/ks/share/resources/ac553236-ddd2-46ef-87ff-06ffbdb7863c/4260bd49-b50a-4785-a79f-1efc653487ac/index_files/f4c149c6-a75d-4b1b-91bc-31714c9dfbb1.png) 21 | 22 | 23 | ## 2. FRP定义 24 | 响应式编程就是异步数据流编程 25 | 26 | 解释1:是一种和事件流有关的编程方式,其角度类似于EventSourceing,关注导致状态值改变的行为事件,一系列事件组成了事件流FRP是更加有效地处理事件流,而无需要显式去管理状态 27 | 1.事件流,离散事件序列 28 | 2.属性properties,代表模型连续的值 29 | 30 | ### 2.1 简单实例 31 | 32 | > var a = function(b,c) {return b+c} 33 | 34 | 理解: 35 | b、c是被`观察者`,a是`观察者`,如果随着`时间推移`,b和c的值`不断变化` 36 | b、c发生的变化的一系列`事件组成事件流`,可以用集合表示`事件流`,FRP做的事情,就是`遍历`这个事件流的`集合`,将导致b和c的变化的时间重新播放,然后a就获取了一系列的值。 37 | 38 | ##### [functional-reactive-programming](https://www.infoq.cn/article/functional-reactive-programming) 39 | 40 | ### 2.2 解释 41 | 事件总线(Event buses)或咱们常见的单击事件就是一个异步事件流,你可以观察这个流,也可以基于这个流做一些自定义操作(原文:side effects,副作用,本文皆翻译为自定义操作)。响应式就是基于这种想法。你能够创建所有事物的数据流,而不仅仅只是单击和悬停事件数据流。 流廉价且无处不在,任何事物都可以当作一个流:变量、用户输入、属性、缓存、数据结构等等。比如,假设你的微博评论就是一个跟单击事件一样的数据流,你能够监听这个流,并做出响应。 42 | 43 | 44 | 最重要的是,有一堆的函数能够创建(create)任何流,也能将任何流进行组合(combine)和过滤(filter)。 这正是“函数式”的魔力所在。一个流能作为另一个流的输入(input),甚至多个流也可以作为其它流的输入。你能合并(merge)两个流。你还能通过过滤(filter)一个流得到那些你感兴趣的事件。你能将一个流中的数据映射(map)到一个新的流中。 45 | 46 | 47 | ###### 更多函数式 48 | - [javascriptallongesix](https://leanpub.com/javascriptallongesix/read) 49 | - [functors_monads_applicatives](http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html#monads) 50 | - [haskell](https://www.haskell.org/tutorial/monads.html) 51 | 52 | 53 | 但是我的理解是: 54 | > f(a)=x(b)+g(c)=> a = f(x(b)g(x)) 55 | 说明: 函数映射关系,代表的是一种映射关系 56 | 57 | --- 58 | ## 3. FP 59 | 60 | ### 3.1 函数式编程历史: 61 | 函数式编程思想的源头可以追溯到 20 世纪 30 年代,数学家阿隆左 . 丘奇在进行一项关于问题的可计算性的研究,也就是后来的 lambda 演算。lambda 演算的本质为 一切皆函数,函数可以作为另外一个函数的输出或者 / 和输入,一系列的函数使用最终会形成一个表达式链,这个表达式链可以最终求得一个值,而这个过程,即为计算的本质。 62 | 63 | 然而,这种思想在当时的硬件基础上很难实现,历史最终选择了同丘奇的 lambda 理论平行的另一种数学理论:图灵机作为计算理论,而采取另一位科学家冯 . 诺依曼的计算机结构,并最终被实现为硬件。由于第一台计算机即为冯 . 诺依曼的程序存储结构,因此运行在此平台的程序也继承了这种基因,程序设计语言如 C/Pascal 等都在一定程度上依赖于此体系。 64 | 65 | 到了 20 世纪 50 年代,一位 MIT 的教授 John McCarthy 在冯 . 诺依曼体系的机器上成功的实现了 lambda 理论,取名为 LISP(LISt Processor), 至此函数式编程语言便开始活跃于计算机科学领域。 66 | 67 | 68 | ### 3.2 命令式编程 && 函数式编程 69 | 70 | 1. 编程风格 71 | ``` 72 | 命令式:一步一步地执行,并且要管理状态的变化 73 | 函数式:描述问题和所需的数据变化以解决问题 74 | ``` 75 | 76 | 2. 状态变化 77 | ``` 78 | 命令式:很重要 79 | 函数式:不存在 80 | ``` 81 | 82 | 3. 执行顺序 83 | ``` 84 | 命令式:很重要 85 | 函数式:不太重要 86 | ``` 87 | 88 | 4. 主要的控制流 89 | ``` 90 | 命令式:循环、条件、函数调用 91 | 函数式:函数调用和递归 92 | ``` 93 | 94 | 5. 主要的操作元 95 | ``` 96 | 命令式 : 结构体和类对象 97 | 函数式:函数作为一等公民的对象进行数据集 98 | ``` 99 | 100 | 函数式语言的语法必须要顾及到特定的设计模式,比如类型推断系统和匿名函数。大体上,这个语言必须实现lambda演算。 并且解释器的求值策略必须是非严格、按需调用的(也叫做延迟执行),它允许不变数据结构和非严格、惰性求值。 101 | 102 | 103 | ### 3.3 js中FP中的应用 104 | OOP(面向对象编程)在占主要的范式在js中,最近,这有一个增长兴趣的编程范式,FP(函数性编程)是一种编程范式,它主要是强调成极小化编程状态的数量。在这个方面,它鼓励的是不可变的数据和纯函数。它也偏向于描述性的风格并且鼓励用好的命名规范的函数,这个允许你清楚的程序当你写逻辑的时候,和可实现细节封装。 105 | 106 | ``` 107 | // A function with a side effect 108 | var x = 10; 109 | const myFunc = function ( y ) { 110 | x = x + y; 111 | } 112 | myFunc( 3 ); 113 | console.log( x ); // 13myFunc( 3 ); 114 | console.log( x ); // 16 115 | ``` 116 | 117 | ``` 118 | 减少副作用:一个副作用是变化的,它不是局部函数带来的影响,一个函数或许做一些事情,像操作DOM,修改一个变量值在更大的作用域内或者写数据到数据库中。这些结果就是副作用这个副作用不是天然的恶魔,一个程序能够产生没有副作用的程序这样就不会影响其他的逻辑, and so there would be no point to it (other than perhaps as a theoretical curiousity). 因此,危险或许应该是可以避免的,所以无论如何是必须严格规范书写。 119 | 120 | 当一个程序产生副作用时,你不得不知道更多关于它的输入和输出,以此来理解这个函数的作用 你必须知道这个程序的上下文和历史的状态,这就使得程序变得难以理解,副作用的带来的bug相互作用造成的在一个不可预测的情况下。并且这个方法产生的副作用是很难被测试出来,但辛亏是它们依赖于上下文和程序的历史状态 121 | 122 | 减少副作用是函数式编程的一个基本原则,大多数情况根据这些因素作为基本准则来理解是可以去避免这些问题。 123 | 数据是不可变化的 124 | ``` 125 | 126 | #### 3.3.1 应用 127 | 128 | ##### 自调函数和闭包 129 | 130 | var ValueAccumulator = function() {var values = [];var accumulate = function(obj) {if (obj) { 131 | values.push(obj.value);return values;} else {return values;}};return accumulate;};//This allows us to do this:var accumulator = ValueAccumulator();accumulator(obj1);accumulator(obj2); 132 | console.log(accumulator());// Output: [obj1.value, obj2.value] 133 | 134 | 135 | 正确的使用闭包 136 | ``` 137 | var outter = []; 138 | function clouseTest2(){ 139 | var array = ["one", "two", "three", "four"]; 140 | for ( var i = 0; i < array.length;i++){ 141 | var x = {}; 142 | x.no = i; 143 | x.text = array[i]; 144 | x.invoke = function (no){ 145 | return 146 | function (){ 147 | print(no); 148 | } 149 | }(i); 150 | outter.push(x); 151 | } 152 | } 153 | ``` 154 | 155 | 通过将函数 柯里化,我们这次为 outter 的每个元素注册的其实是这样的函数: 156 | ``` 157 | //x == 0 158 | x.invoke = function (){print(0);} 159 | //x == 1 160 | x.invoke = function (){print(1);} 161 | //x == 2 162 | x.invoke = function (){print(2);} 163 | //x == 3 164 | x.invoke = function (){print(3);} 165 | ``` 166 | 这样,就可以得到正确的结果了。 167 | 168 | ##### 高阶函数 169 | 自调用函数实际上是高阶函数的一种形式。高阶函数就是以其它函数为输入,或者返回一个函数为输出的函数。 170 | 171 | 高阶函数在传统的编程中并不常见。当命令式程序员使用循环来迭代数组的时候,函数式程序员会采用完全不同的一种实现方式。 通过高阶函数,数组中的每一个元素可以被应用到一个函数上,并返回新的数组。 172 | 173 | 这是函数式编程的中心思想。高阶函数具有把逻辑像对象一样传递给函数的能力。 174 | 175 | ``` 176 | // 使用forEach()来遍历一个数组,并对其每个元素调用回调函数accumulator2 177 | var accumulator2 = ValueAccumulator(); 178 | var objects = [obj1, obj2, obj3]; // 这个数组可以很大 179 | objects.forEach(accumulator2); 180 | console.log(accumulator2()); 181 | ``` 182 | 183 | ##### 纯函数 184 | 纯函数返回的计算结果仅与传入的参数相关,不会使用外部的函数和全局的状态,并且没有副作用。换句话说就是不能改变作为传入的变量,所以程序里智能使用纯函数返回的值。 185 | ``` 186 | // 把信息打印到屏幕中央的函数var printCenter = function(str) {var elem = document.createElement("div"); 187 | elem.textContent = str; 188 | elem.style.position = 'absolute'; 189 | elem.style.top = window.innerHeight / 2 + "px"; 190 | elem.style.left = window.innerWidth / 2 + "px"; 191 | document.body.appendChild(elem);};printCenter('hello world');// 纯函数完成相同的事情var printSomewhere = function(str, height, width) {var elem = document.createElement("div"); 192 | elem.textContent = str; 193 | elem.style.position = 'absolute'; 194 | elem.style.top = height; 195 | elem.style.left = width;return elem;}; 196 | document.body.appendChild(printSomewhere('hello world', 197 | window.innerHeight / 2) + 10 + "px", 198 | window.innerWidth / 2) + 10 + "px")); 199 | ``` 200 | 201 | ##### 匿名函数 202 | 在函数式编程语言中,函数是可以没有名字的,匿名函数通常表示:“可以完成某件事的一块代码”。这种表达在很多场合是有用的,因为我们有时需要用函数完成某件事,但是这个函数可能只是临时性的,那就没有理由专门为其生成一个顶层的函数对象。 203 | 204 | 它允许了在现场定义临时逻辑能力。通常这里带来的好处,就是某一个函数只用一次,就没有必要给它良妃一个变量名 205 | 匿名函数不仅仅是语法糖,他们是lambda演算的化身。请听我说下去…… lambda演算早在计算机和计算机语言被发明的很久以前就出现了。它只是个研究函数的数学概念。 非同寻常的是,尽管它只定义了三种表达式:变量引用,函数调用和匿名函数,但它被发现是图灵完整的。 如今,lambda演算处于所有函数式语言的核心,包括javascript。由于这个原因,匿名函数往往被称作lambda表达式。 206 | 207 | ##### 柯里化 208 | 柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 209 | 210 | 211 | 212 | --- 213 | ###### 思考 214 | - 电路时序和FRP有什么关联呢? 215 | - FRP和EDA是什么关系呢? 216 | 217 | --- 218 | ###### 更多学习 219 | - [raym0ndkwan](http://blog.csdn.net/raym0ndkwan/article/details/8195592) 220 | - [nowamagic1](http://www.nowamagic.net/librarys/veda/detail/2488) 221 | - [nowamagic2](http://www.nowamagic.net/librarys/veda/detail/245) 222 | -------------------------------------------------------------------------------- /STOMP.md: -------------------------------------------------------------------------------- 1 | ## STOMP 协议总结 2 | STOMP是一种基础Frame的协议,模仿HTTP的Frame。一个Frame由命令、一组可选择的信息头和一个信息体组成。STOMP协议是基于文本的,也可以传递二进制信息。协议默认UTF-8编码,也支持对信息体的其他特定可选择的编码。 3 | 4 | STOMP服务器被定义为一组可以接收发送的信息的目标服务。STOMP视目标服务为一个不可读的字符串并且它的特定语义由服务端实现,而且STOMP没有规定传输的目标服务的语法,不同服务之间传递的信息的语义也可以不相同。这使得服务端可以在STOMP支持的语义中自由选择。 5 | 6 | - 一个STOMP客户端是一个可以以两种模式运行的用户代理,可能是同时运行两种模式。 7 | 8 | - 作为生产者,通过SEND框架将消息发送给服务器的某个服务 9 | - 作为消费者,通过SUBSCRIBE制定一个目标服务,通过MESSAGE框架,从服务器接收消息。 10 | 11 | ### 设计理念 12 | STOMP的主要设计理念就是简易性和可操作性。 13 | 14 | STOMP被设计成一个轻量级协议,这样很容易使用众多的开发语言实现客户端及服务器。这意味着,特别是对服务器的结构和特性没有过多的限制,例如命名规则和实现语法的可靠性。 15 | 16 | 17 | 18 | ### 协议组成 19 | STOMP是一个基于Frame的协议,它假定在底层存在一个可靠地双向数据流的网络协议,就像TCP协议一样。客户端和服务端通过STOMP协议定义的Frame进行通信,一个Frame的结构大致如下: 20 | 21 | `frame = a command + a set of optional headers + an optional body` 22 | 23 | ``` 24 | COMMAND 25 | header1:value1 26 | header2:value2 27 | 28 | Body^@ 29 | ``` 30 | - 这个Frame以一个指令字符串开始,以换行符(EndOfLine EOL,即换行符)结束,指令由一个可选的回车(13字节)紧跟着一个必须添加的换行(10字节)组成。接着是零或者多个以:格式组成的头实体。每一个头实体均以EOL结束。一个空行,即一个额外的EOL表示头部信息结束及Body信息开始。Body后面跟随着一个八进制NULL字符,文档中的例子使用了^@,在ASCII码中的控制符-@,用它来表示NULL。NULL可以跟随多个EOL。更多关于如何解析STOMPFrame的信息,查看本文档的补充反馈章节。 31 | 32 | - 文档中提到的所有的指令和头的名字都是对大小写敏感的。 33 | 34 | 35 | ### 其他说明 36 | - SEND, MESSAGE, and ERROR 可以有body,其他的FRAME是没有Body 37 | 38 | 39 | 40 | - SEND, MESSAGE and ERROR frames 应该包含 a content-type header to help the receiver of the frame interpret its body. 41 | 42 | - 如果设置了`content-type`, body必须使用 `MIME type` . 否则,接收方必须考虑使用a binary blob的body. 43 | ``` 44 | accessor.setContentType(new MimeType("text", "plain", StandardCharsets.UTF_8)); 45 | 46 | ``` 47 | 48 | Frame 如下所示 49 | ``` 50 | MESSAGE 51 | subscription:0 52 | message-id:007 53 | destination:/queue/a 54 | content-type:text/plain 55 | 56 | hello queue a^@ 57 | ``` 58 | - 文档中提到的所有的指令和头的名字都是对大小写敏感的。 59 | 60 | 61 | 62 | ## FRAME 63 | `STOMP` 基于可靠的双向流(比如:`TCP`) 64 | 65 | ### CONNECT 66 | 67 | - `Client-->Server` 客户端发起TCP连接 68 | ``` 69 | CONNECT 70 | accept-version:1.2 71 | host:stomp.github.org 72 | 73 | ^@ 74 | ``` 75 | 76 | - `Server--> Client` 服务端返回 77 | 78 | CONNECTED或者ERROR 79 | 80 | ``` 81 | CONNECTED 82 | version:1.2 83 | 84 | ^@ 85 | ``` 86 | 服务端拒绝连接出错或者拒绝连接时使用`ERROR`。 87 | 88 | [代码详见](https://github.com/WeBankFinTech/WeEvent/blob/8726eea3ec828c25691666196c0c2ace9cb584a0/weevent-broker/src/main/java/com/webank/weevent/protocol/stomp/BrokerStomp.java#L151) 89 | 90 | - 必要参数 91 | - COMMAND:CONNECT 92 | - version 版本 93 | - 推荐参数 94 | - login : 客户端登陆名 95 | - passcode : 客户端登陆密码 96 | - heart-beat : The Heart-beating settings. 97 | - 说明:1.2 版本有所不同,比如`host`. 98 | 99 | ### 协商 100 | #### Version 101 | 1. 客户端可以支持的版本`1.0,1.1,2.0` 102 | ``` 103 | CONNECT 104 | accept-version:1.0,1.1,2.0 105 | host:stomp.github.org 106 | 107 | ^@ 108 | ``` 109 | 2. 服务端返回支持的协议 110 | ``` 111 | CONNECTED 112 | version:1.1 113 | 114 | ^@ 115 | ``` 116 | 117 | ``` 118 | ERROR 119 | version:1.2,2.1 120 | content-type:text/plain 121 | 122 | Supported protocol versions are 1.2 2.1^@ 123 | ``` 124 | 125 | #### heart-beat 126 | 127 | TCP链接的健康性 128 | - 第一个数值表示发送Frame者能做什么(接收心跳) 129 | 130 | 0意味着它不能发出心跳。 131 | 否则该数值就是它确认可以发出的最小毫秒数心跳的间隔。 132 | 133 | - 第二个数值表示发送Frame者希望收到的(接收心跳) 134 | 135 | 0意味着它不希望接受到心跳。 136 | 否则该数值就是它希望收到收到的心跳间隔毫秒数。 137 | 138 | ``` 139 | CONNECT 140 | heart-beat:, 141 | 142 | CONNECTED: 143 | heart-beat:, 144 | ``` 145 | 146 | 147 | 对于从客户端到服务端的心跳: 148 | 149 | 如果是0或者是0,那么就不会有心跳发生。 150 | 否则就会每MAX(,)毫秒接发生一次心跳。 151 | 从另一方面来说,也是同样的道理。 152 | 153 | 对于心跳来说,从网络连接上接收到的任何数据都表示远端是正常运行的。在给定的方向上,如果希望心跳每毫秒秒跳动一次,需要确保如下几点: 154 | 155 | 发送者必须至少每毫秒通过建立的网络连接发送一次新的数据。 156 | 如果发送者没有STOMP帧要发送时,它需要发送一个EOL。 157 | 如果在至少毫秒内接收者没有接收到任何数据,那么可以认为链接已经断开。 158 | 由于定时是不一定准确的,接受者应该容忍并且考虑一个误差范围。 159 | 160 | 161 | ## Client FRAME 162 | 客户端如果发送了一个不在如下列表范围内的帧,对于1.2协议的服务器可能会返回一个ERROR,然后关闭连接。 163 | 164 | 客户端帧列表包括: 165 | 166 | ```SEND、SUBSCRIBE、UNSUBSCRIBE、ACK、NACK、BEGIN、COMMIT、ABORT、DISCONNECT。``` 167 | 168 | 我们`Client`目前实现了: 169 | 170 | 171 | ```SEND、SUBSCRIBE、UNSUBSCRIBE、DISCONNECT。``` 172 | 173 | 174 | 175 | ### SEND 176 | SEND帧发送一个消息到消息系统中的某个目标服务。它有一个必须包含的头“destination”,表示应该把消息发送到的目的服务。SEND帧的body包含需要发送的消息内容。 177 | 178 | - `Client-->Server` 179 | 180 | ``` 181 | SEND 182 | destination:/queue/a 183 | content-type:text/plain 184 | 185 | hello queue a 186 | ^@ 187 | ``` 188 | - 用户可以向SEND帧中添加任意用户自定义的头信息。用户自定义头一般来说用来允许用户通过SUBSCRIBE帧中的一个标示用户自定义的头信息的内容去过滤消息。用户自定义的头信息必须通过MESSAGE帧传递。 189 | 190 | - 如果服务端因为任何原因不能成功的处理SEND帧内容,需要返回一个ERROR并且断开连接。 191 | - 必要参数 192 | - COMMAND:SEND 193 | - content-length 194 | - body 195 | 196 | - 推荐参数 197 | 198 | - `Server--> Client` 199 | ``` 200 | RECEIPT 201 | ``` 202 | 203 | 204 | 205 | - 说明:1.2 版本 206 | 207 | [代码详见](https://github.com/WeBankFinTech/WeEvent/blob/8726eea3ec828c25691666196c0c2ace9cb584a0/weevent-broker/src/main/java/com/webank/weevent/protocol/stomp/BrokerStomp.java#L169) 208 | 209 | #### SUBSCRIBE 210 | `SUBSCRIBE`帧被用于注册对一个目标服务的监听。跟`SEND`一样,`SUBSCRIBE`需要`destination`头标示需要订阅的目标服务。被订阅的目标服务收到的任何信息以后都会被以MESSAGE帧的形式发送给客户端。 211 | 212 | ``` 213 | SUBSCRIBE 214 | id:0 215 | destination:/queue/foo 216 | ack:client 217 | 218 | ^@ 219 | ``` 220 | 221 | - 如果服务端不能成功生成订阅,应该返回一个ERROR并且断开连接。 222 | 223 | - STOMP服务端可以支持额外的服务端特定的头去定制目标服务的传递语义。比如我们扩展的`event-id`。 224 | 225 | - id说明:由于一个打开的连接可以订阅服务端上的多个目标服务,所以包含在一个帧中的id头的值必须是唯一标示一个订阅。这个id用来客户端和服务端处理与订阅消息和取消订阅相关的动作。在同一个链接中,不同的订阅必须使用不同的标示符。 226 | 227 | 228 | 229 | 230 | ### UNSUBSCRIBE 231 | `UNSUBSCRIBE`用来移除一个已经存在订阅,一旦一个订阅被从连接中取消,那么客户端就再也不会收到来自这个订阅的消息。由于一个连接可以添加多个服务端的订阅,所以`id`头是`UNSUBSCRIBE`必须包含的,用来唯一标示要取消的是哪一个订阅。`id`的值必须是一个已经存在的订阅的标识。 232 | 233 | 234 | 235 | - `Client-->Server` 236 | 237 | ``` 238 | UNSUBSCRIBE 239 | id:0 240 | 241 | ^@ 242 | ``` 243 | 244 | 245 | - `Server--> Client` 246 | ``` 247 | RECEIPT 248 | ``` 249 | 250 | #### DISCONNECT 251 | 客户端可以通过关闭Socket而随时与服务端断开链接,但是这样不能确认先前发出的帧是否已经到达服务器。如果想要实现正常断开,即客户端已经知道之前的帧都已经成功被服务端接收,客户端应该做如下内容: 252 | 253 | 254 | - `Client-->Server` 255 | 256 | ``` 257 | DISCONNECT 258 | receipt:77 259 | ^@ 260 | ``` 261 | 262 | 263 | - `Server--> Client` 264 | ``` 265 | RECEIPT 266 | receipt-id:77 267 | ^@ 268 | ``` 269 | 270 | ## Server 271 | 服务端有时会发送除CONNECTED帧之外的下列帧到客户端:MESSAGE、RECEIPT及ERROR。 272 | 273 | 274 | 275 | ### MESSAGE 276 | 277 | MESSAGE用于传输从服务端订阅的消息到客户端。 278 | 279 | MESSAGE中必须包含destionation头,用以表示这个消息应该发送的目标。如果这个消息被使用STOMP发送,那么这个destionation应该与相应的SEND帧中的目标一样。 280 | 281 | MESSAGE中必须包含message-id头,用来唯一表示发送的是哪一个消息,以及subscription头用来表示接受这个消息的订阅的唯一标示。 282 | MESSAGE如果有body内容,则必须包含content-length和content-type头。 283 | 284 | 285 | ``` 286 | MESSAGE 287 | subscription:0 288 | message-id:007 289 | destination:/queue/a 290 | content-type:text/plain 291 | 292 | hello queue a^@ 293 | ``` 294 | - MESSAGE中还可以包含所有用户定义的头以服务端额外特别添加的头。但是用户一定要将信息写入到`NativeHeader` 295 | - `accessor.setNativeHeader("event-id", EventId);` 296 | 297 | ### RECEIPT 298 | 299 | RECEIPT是服务端对于相应客户端需要回执的Frame的确认。 300 | 301 | ``` 302 | RECEIPT 303 | receipt-id:message-12345 304 | 305 | ^@ 306 | ``` 307 | 308 | ### ERROR 309 | 如果连接过程中出现什么错误,服务端就会发送ERROR。在这种情况下,服务端发出ERROR之后必须马上断开连接。 310 | 311 | --- 312 | ## JAVA Server 313 | ### setNativeHeader 314 | 所有的`Frame` 的值,建议使用`setNativeHeader`,写入所有的值自定义值或者非必要参数。 315 | ``` 316 | accessor.setNativeHeader("receipt-id", headerIdStr); 317 | ``` 318 | 说明:因为java库的bug,采用该方案进行容错。 319 | 320 | ### Server维护id值对应的关系 321 | 连接层-->协议层-->应用层 322 | ``` 323 | // session id <-> [header subscription id in stomp <-> (subscription id in consumer, topic)] 324 | private static Map>> sessionContext; 325 | ``` 326 | 327 | 328 | ==思考题==: 329 | - 从订阅的角度,订阅者订阅成功后,服务端给监听到信息,并且响应给到Client,怎么保证是订阅者订阅的信息,正确且信息唯一? 330 | 331 | ---- 332 | ##### 其他需要关注的问题 333 | - Client重连的问题 334 | - heartBeat 335 | - 协议编码说明 336 | - Server端和Client的ID对应关系 337 | 338 | 339 | --- 340 | ## 笔记 341 | 342 | ### 1. websocket 343 | web的技术大概可以分为3类:轮询/streaming/websocket 344 | 345 | 相对于传统的HTTP长连接,WebSocket的优点在于: 346 | ``` 347 | 真正的双向通信。而HTTP只能由客户端发起请求。 348 | HTTP请求中带有大量的header,很多冗余信息,其实很多流量被浪费掉了,WebSocket则没有这个问题。 349 | WebSocket协议支持各种Extension,可以实现多路复用等功能。 350 | ``` 351 | WebSocket虽然是独立于HTTP的另一种协议,但建立连接时却需要借助HTTP协议进行握手,这也是WebSocket的一个特色,利用了HTTP协议中一个特殊的header:Upgrade。在双方握手成功后,就跟HTTP没什么关系了,会直接在底层的TCP Socket基础上进行通信。 352 | 353 | 354 | ### 2. STOMP 355 | 356 | STOMP is a simple text-orientated messaging protocol. 357 | It defines an interoperable wire format so that any of the available STOMP clients can communicate with 358 | any STOMP message broker to provide easy and widespread messaging interoperability among languages and 359 | platforms (the STOMP web site has a list of STOMP client and server implementations. 360 | 361 | STOMP中的消息都被抽象为“帧”(有点类似AMQP中message的概念),帧的格式和HTTP非常类似,分为command、header、body三部份。其中比较重要的就是SUBSCRIBE/SEND/MESSAGE帧。SUBSCIRBE帧用于订阅某个destination,SEND帧用于发送数据,MESSAGE帧用于从服务端接收数据。尤其注意下其中的destination header,有点像传统mq中的topic。STOMP不限定destination的格式,可以是任意格式字符串,由服务端去解释,不过一般都是/a/b这种类似路径的格式。 362 | 363 | ![image](https://ask.qcloudimg.com/http-save/1651485/czssxt74a6.png?imageView2/2/w/1620) 364 | 365 | ### 3. WebSocket、SockJs、STOMP三者关系 366 | 367 | 简而言之,WebSocket 是底层协议,SockJS 是WebSocket 的备选方案,也是底层协议,而 STOMP 是基于 WebSocket(SockJS)的上层协议。 368 | 369 | 1、HTTP协议解决了 web 浏览器发起请求以及 web 服务器响应请求的细节,假设 HTTP 协议 并不存在,只能使用 TCP 套接字来 编写 web 应用。 370 | 371 | 2、直接使用 WebSocket(SockJS) 就很类似于 使用 TCP 套接字来编写 web 应用,因为没有高层协议,就需要我们定义应用间所发送消息的语义, 372 | 还需要确保连接的两端都能遵循这些语义; 373 | 374 | 3、同HTTP在TCP 套接字上添加请求-响应模型层一样,STOMP在WebSocket 之上提供了一个基于帧的线路格式层,用来定义消息语义; 375 | 376 | ## 4. 应用场景说明 377 | - 后端系统内部的消息队列 378 | --- 379 | ## 5. Client 380 | ### 5.1 快速理解 381 | [spring demo](https://github.com/spring-guides/gs-messaging-stomp-websocket) 382 | 该例子可以帮助用户搭建一个简易的服务端,并且包含一个web端,可以帮助用户快速理解协议Server端和Client端。 383 | 384 | ### 5.2 python client端 385 | [stomp.py](https://github.com/jasonrbriggs/stomp.py) 386 | 387 | --- 388 | 更多 389 | 390 | - [stomp](https://stomp.github.io/) 391 | - [stomp.js v4](https://github.com/jmesnil/stomp-websocket) 这个是旧版本,可以考虑使用新版本 392 | - [stomp.js v5](https://github.com/stomp-js/stompjs) 393 | - [sockjs](https://github.com/sockjs/sockjs-client) 394 | - [rfc](https://tools.ietf.org/html/rfc6455) 395 | 396 | --- 397 | 推荐阅读 398 | - [BBF_USP_webinar](https://www.broadband-forum.org/downloads/webinars/BBF_USP_webinar_2018-02-28.pdf) 399 | - [mqtt协议](https://www.ibm.com/developerworks/cn/iot/iot-mqtt-why-good-for-iot/index.html) 400 | 协议标准 401 | 402 | - [stomp-specification-1.0](https://stomp.github.io/stomp-specification-1.0.html) 403 | - [stomp-specification-1.1](https://stomp.github.io/stomp-specification-1.1.html) 404 | - [stomp-specification-1.2](https://stomp.github.io/stomp-specification-1.2.html) 405 | 406 | 407 | -------------------------------------------------------------------------------- /grafana-influxdb-telegraf.md: -------------------------------------------------------------------------------- 1 | ## 1.Install 2 | 3 | ### 1.1. influxdb 4 | 5 | ``` 6 | sudo yum install influxdb 7 | sudo systemctl start influxdb 8 | ``` 9 | 10 | 判断已经安装完成,输入下面的命令,可以进入influxDB的界面 11 | ``` 12 | > influx 13 | ``` 14 | 15 | ### 1.2. Telegraf 修改版本 16 | ``` 17 | wget https://dl.influxdata.com/telegraf/releases/telegraf-1.9.1_linux_amd64.tar.gz 18 | tar xf telegraf-1.9.1_linux_amd64.tar.gz 19 | telegraf -version 20 | ``` 21 | 22 | #### 1.2.3 启动服务 23 | 24 | config: /etc/telegraf/telegraf.conf 25 | 26 | ``` 27 | sudo systemctl start telegraf 28 | sudo systemctl status telegraf 29 | sudo systemctl enable telegraf 30 | ``` 31 | 32 | ### 1.3. Grafana 修改版本 33 | #### 1.3.1 安装grafana 34 | ``` 35 | wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.2-1.x86_64.rpm 36 | ``` 37 | #### 1.3.2 启动服务、添加开机启动: 38 | ``` 39 | systemctl enable grafana-server 40 | systemctl start grafana-server 41 | ``` 42 | 43 | #### 1.3.3 配置说明 44 | ``` 45 | # 配置文件 /etc/grafana/grafana.ini 46 | # systemd服务名 grafana-server.service 47 | # 默认日志文件 /var/log/grafana/grafana.log 48 | # 默认数据库文件 /var/lib/grafana/grafana.db 49 | ``` 50 | 51 | #### 1.3.4 add plugin 52 | 添加插件 53 | 54 | ``` 55 | sudo grafana-cli plugins install grafana-clock-panel 56 | sudo systemctl restart grafana-server 57 | ``` 58 | 59 | 60 | 61 | --- 62 | ## 2. grafana 需要关注的几个点 63 | ### 2.1 Metric 64 | 65 | For Mode there are three options: 66 | 67 | The default option is Time and means the x-axis represents time and that the data is grouped by time (for example, by hour or by minute). 68 | 69 | The Series option means that the data is grouped by series and not by time. The y-axis still represents the value. 70 | The Histogram option converts the graph into a histogram. A Histogram is a kind of bar chart that groups numbers into ranges, 71 | often called buckets or bins. 72 | Taller bars show that more data falls in that range. Histograms and buckets are described in more detail here. 73 | 74 | 75 | 76 | ### 2.2 Variables 77 | Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. 78 | 79 | 80 | ### 2.3 templating 81 | 时间间隔 82 | ``` 83 | 1. 选择 New 按钮新建一个模板变量 84 | 2. 选择 Interval 变量类型,我们可以用这种变量表达时间间隔,同时设置 Name 和 Label,Name 是变量名称,实际引用的时候用$变量名称进行引用;Label 本身无实际作用,主要是用来展示在界面,让用户更加容易理解的。 85 | 3. 可以看到在 Values 中,已经有大量预置的时间间隔,我们可以在其中增加,诸如 1m(1分钟),1h(1小时),1d(1天)等时间间隔变量 86 | 在界面,我们可以见到已经生成了名为时间间隔的下拉框列表,列表中包括了我们设置的时间间隔预设值 87 | 4. 将时序查询的 interval 设置为 $t (t 为我们设置的变量Name)。此时在下拉框里选择不同的时间间隔,图表将随之进行切换。 88 | ``` 89 | 基于查询结果的下拉列表 90 | ``` 91 | 92 | 前置步骤请参考时间间隔变量设置 93 | 选择Query 类型 94 | Data source 选择你查询的目标数据源 95 | Query 是查询所有可能值的查询语句,ES/Logdb 的查询方式是{"find": "terms", "field": "status"},其中status 是我们查询的目标字段,在这里可以替换成你需要的字段。更深入的语法请参考 ES 官方文档。 96 | Regex 可以选择对于返回的状态值进行正则表达式过滤 97 | Sort 选择排序方式 98 | Multi-value 控制下拉框是否可以支持多选,如果不选中则只能单选 99 | Include all value 控制是否可以支持All选项,支持全选所有的值,只在多选的模式下有效果 100 | Preview of values 可以预览这个字段的所有值 101 | ``` 102 | 103 | [templating](http://docs.grafana.org/reference/templating/) 104 | 105 | #### 2.4 provisioning 106 | 1. edit the config grafana.ini 107 | ``` 108 | # folder that contains provisioning config files that grafana will apply on startup and while running. 109 | ;provisioning = conf/provisioning 110 | ``` 111 | 2. add the dashborads.yaml and db.yaml file, location in `/etc/grafana/provisioning/dashborads` and `/etc/grafana/provisioning/databases` 112 | 113 | 114 | ## 3. 常见问题 115 | ### 3.1 how to get the parameter from the url 116 | for example, nodename 117 | 1. set `Custom Variables` ,name as `nodename` 118 | 2. add the parameter `var-nodename=“test”`,such as 119 | ``` 120 | Use Url http://servername:3000/dashboard/db/dashboard?refresh=10s&var-nodename=“test” 121 | ``` 122 | 123 | 124 | 3. In Query: use where clause as shown below: 125 | ``` 126 | WHERE nodename =$nodename 127 | ``` 128 | you can see the output 129 | 130 | ``` 131 | select * 132 | from table 133 | where nodename ="test" 134 | ``` 135 | 136 | 137 | 138 | ### 3.2 nginx 反向代理到 grafana 139 | 140 | grafana配置nginx反向代理 141 | 142 | 将grafana配到www.myserver.com域名的/grafana/的location下 143 | 144 | 1. nginx配置 145 | ``` 146 | location /grafana/ { 147 | proxy_pass http://grafana_server:3000/; 148 | proxy_set_header Host $host; 149 | } 150 | ``` 151 | 152 | 2. grafana配置文件修改 153 | 154 | ``` 155 | #在/etc/grafana/grafana.ini配置文件中修改 156 | domain = www.myserver.com 157 | root_url = %(protocol)s://%(domain)s/grafana 158 | ```` 159 | 160 | ### 3.3 进行授权 161 | 进用户授权行授权,比如说,部分用户可以进行匿名进行访问页面。 162 | 163 | 1. 修改`grafana.ini`的配置 164 | ``` 165 | [auth.anonymous] 166 | # 设置允许匿名 167 | enabled = true 168 | 169 | # 设置允许匿名的组织 170 | org_name = Main Org. 171 | 172 | # 设置允许匿名的组织角色 173 | org_role = Viewer 174 | ``` 175 | 2. 重启 176 | ``` 177 | systemctl restart grafana-server 178 | ``` 179 | 180 | 181 | --- 182 | 183 | ## 4. influxDB+telegraf 184 | 185 | ![image](https://www.influxdata.com/wp-content/uploads/Tick-Stack-Telegraf-2.png) 186 | 187 | POLICY 188 | 189 | ``` 190 | > CREATE RETENTION POLICY "2h0m0s" ON "telegraf" DURATION 2h REPLICATION 1 DEFAULT 191 | > SHOW RETENTION POLICIES ON telegraf 192 | name duration shardGroupDuration replicaN default 193 | ---- -------- ------------------ -------- ------- 194 | autogen 0s 168h0m0s 1 false 195 | 2h0m0s 2h0m0s 1h0m0s 1 true 196 | ``` 197 | 198 | ``` 199 | SELECT time,host,usage_system FROM "autogen".cpu limit 2 200 | name: cpu 201 | time host usage_system 202 | ---- ---- ------------ 203 | 1526008670000000000 VM_42_233_centos 1.7262947210419817 204 | 1526008670000000000 VM_42_233_centos 1.30130130130254 205 | ``` 206 | 207 | ``` 208 | SELECT 100 - usage_idel FROM "autogen"."cpu" WHERE time > now() - 1m and "cpu"='cpu0' 209 | ``` 210 | 211 | ### 4.1 监听多台服务 212 | 213 | 1. 在需要监控的机器上面安装对应的telegraf 214 | 2. 并且配置上报的influxdb的机器和数据库 215 | ``` 216 | #Configuration for influxdb server to send metrics to 217 | 218 | [[outputs.influxdb]] 219 | 220 | urls = [“http://1x.xxx:8086”] #influxdb地址 221 | 222 | database = “telegraf_ali” # required #influxdb数据库 223 | 224 | retention_policy = “”#数据保留策略 225 | 226 | write_consistency = “any” #数据写入策略,仅适用于集群模式 227 | 228 | timeout = “5s” #写入超时策略 229 | 230 | username = “telegraf_ali” #数据库用户名 231 | 232 | password = “gPHhbeh” #数据库密码 233 | 234 | #user_agent = “telegraf” #采集器代理名称 235 | ``` 236 | 237 | 练习 238 | 239 | 1. A机器部署`influxdb+telegraf` 240 | ``` 241 | > influx 242 | > use telegraf; 243 | > SHOW TAG VALUES FROM system WITH KEY=host 244 | # 可以看到一台主机的信息 245 | ``` 246 | 247 | 2. B机器部署`telegraf` 248 | 3. 在B机器,修改`telegraf` `influxdb`地址,使用默认telegraf 249 | 4. 重启机器B 的`telegraf`机器 250 | 进入A机器 251 | ``` 252 | > influx 253 | > use telegraf; 254 | > SHOW TAG VALUES FROM system WITH KEY=host 255 | 256 | ``` 257 | - 上面查询主机的信息1条--> 两条主机信息,说明操作成功 258 | 259 | 260 | #### 4.1.1 COMMAND 261 | ``` 262 | SHOW MEASUREMENTS --查询当前数据库中含有的表 263 | SHOW FIELD KEYS --查看当前数据库所有表的字段 264 | SHOW series from pay --查看key数据 265 | SHOW TAG KEYS FROM "pay" --查看key中tag key值 266 | SHOW TAG VALUES FROM "pay" WITH KEY = "merId" --查看key中tag 指定key值对应的值 267 | SHOW TAG VALUES FROM cpu WITH KEY IN ("region", "host") WHERE service = 'redis' 268 | DROP SERIES FROM WHERE ='' --删除key 269 | SHOW CONTINUOUS QUERIES --查看连续执行命令 270 | SHOW QUERIES --查看最后执行命令 271 | KILL QUERY --结束命令 272 | SHOW RETENTION POLICIES ON mydb --查看保留数据 273 | 查询数据 274 | SELECT * FROM /.*/ LIMIT 1 --查询当前数据库下所有表的第一行记录 275 | select * from pay order by time desc limit 2 276 | select * from db_name."POLICIES name".measurement_name --指定查询数据库下数据保留中的表数据 POLICIES name数据保留 277 | 删除数据 278 | delete from "query" --删除表所有数据,则表就不存在了 279 | drop MEASUREMENT "query" --删除表(注意会把数据保留删除使用delete不会) 280 | DELETE FROM cpu 281 | DELETE FROM cpu WHERE time < '2000-01-01T00:00:00Z' 282 | DELETE WHERE time < '2000-01-01T00:00:00Z' 283 | DROP DATABASE “testDB” --删除数据库 284 | DROP RETENTION POLICY "dbbak" ON mydb --删除保留数据为dbbak数据 285 | DROP SERIES from pay where tag_key='' --删除key中的tag 286 | 287 | SHOW SHARDS --查看数据存储文件 288 | DROP SHARD 1 289 | SHOW SHARD GROUPS 290 | SHOW SUBSCRIPTIONS 291 | 292 | ``` 293 | 294 | --- 295 | ### 4.2 grafana tools 296 | 297 | 298 | ``` 299 | - [Puppet](https://forge.puppet.com/puppet/grafana) 300 | - [Ansible](https://github.com/cloudalchemy/ansible-grafana) 301 | - [Chef](https://github.com/JonathanTron/chef-grafana) 302 | - [Saltstack](https://github.com/salt-formulas/salt-formula-grafana) 303 | - [Jsonnet](https://github.com/grafana/grafonnet-lib/) 304 | - [quick install](https://github.com/samuelebistoletti/docker-statsd-influxdb-grafana) 305 | 306 | ``` 307 | 308 | #### 4.2.1 [quick install](https://github.com/samuelebistoletti/docker-statsd-influxdb-grafana) 309 | 310 | Centos 7 docker 启动grafana容器报"iptables No chain/target/match by that name" 311 | 312 | ``` 313 | docker run -d -p 3000:3000 grafana/grafana:5.1.0 314 | Error response from daemon: Cannot start container 565c06efde6cd4411e2596ef3d726817c58dd777bc5fd13762e0c34d86076b9e: iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3888 -j DNAT --to-destination 192.168.42.11:3888 ! -i docker0: iptables: No chain/target/match by that name 315 | ``` 316 | 317 | #### 4.2.2 解决方法: 318 | 319 | vim /etc/sysconfig/iptables 320 | 321 | ``` 322 | *nat 323 | :PREROUTING ACCEPT [27:11935] 324 | :INPUT ACCEPT [0:0] 325 | :OUTPUT ACCEPT [598:57368] 326 | :POSTROUTING ACCEPT [591:57092] 327 | :DOCKER - [0:0] 328 | -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER 329 | -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER 330 | -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE 331 | COMMIT 332 | *filter 333 | :INPUT ACCEPT [0:0] 334 | :FORWARD ACCEPT [0:0] 335 | :OUTPUT ACCEPT [0:0] 336 | :DOCKER - [0:0] 337 | -A INPUT -i lo -j ACCEPT 338 | -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 339 | -A INPUT -s 10.0.0.0/8 -j ACCEPT 340 | -A INPUT -p tcp -m state --state NEW -m tcp --dport 10050 -j ACCEPT 341 | -A INPUT -s 172.16.0.0/12 -j ACCEPT 342 | -A INPUT -s 192.168.0.0/16 -j ACCEPT 343 | -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP 344 | -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 345 | -A INPUT -p tcp -m tcp --dport 3000 -j ACCEPT 346 | -A INPUT -p tcp -m tcp --dport 36091 -j ACCEPT 347 | -A INPUT -j DROP 348 | -A FORWARD -j DROP 349 | -A OUTPUT -j ACCEPT 350 | COMMIT 351 | ``` 352 | 353 | 354 | ## 5. remove 355 | 356 | ### 5.1 remove influxdb 357 | 卸载命令: 358 | 359 | ``` 360 | [root@localhost shared]# rpm -q influxdb 361 | influxdb-0.8.7-1.x86_64 362 | [root@localhost shared]# rpm -e influxdb 363 | [root@localhost shared]# rpm -q influxdb 364 | package influxdb is not installed 365 | ``` 366 | 367 | 参数说明: 368 | 369 | 首先通过 rpm -q <关键字> 可以查询到rpm包的名字 370 | 然后 调用 rpm -e <包的名字> 删除特定rpm包 371 | 如果遇到依赖,无法删除,使用 rpm -e --nodeps <包的名字> 不检查依赖,直接删除rpm包 372 | 如果恰好有多个包叫同样的名字,使用 rpm -e --allmatches --nodeps <包的名字> 删除所有相同名字的包, 并忽略依赖 373 | 删除完后,清除已有文件: 374 | 375 | ``` 376 | [root@localhost opt]# ls 377 | influxdb 378 | [root@localhost opt]# rm -rf influxdb 379 | [root@localhost opt]# ls 380 | ```` 381 | 处理端口占用 382 | 383 | ``` 384 | name=$(lsof -i:8086|tail -1|awk '"$1"!=""{print $2}') 385 | if [ -z $name ] 386 | then 387 | echo "No process can be used to killed!" 388 | exit 0 389 | fi 390 | id=$(lsof -i:8086|tail -1|awk '"$1"!=""{print $2}') 391 | kill -9 $id 392 | 393 | echo "Process name=$name($id) kill!" 394 | exit 0 395 | ``` 396 | ### 5.2remove grafana 397 | 移除命令 398 | ``` 399 | sudo yum remove grafana 400 | ``` 401 | ### 5.3remove telegraf 402 | ``` 403 | sudo yum remove telegraf 404 | ``` 405 | -------------------------------------------------------------------------------- /Serverless.md: -------------------------------------------------------------------------------- 1 | ## 1. Event brokering 2 | 3 | ### 1.1 Event brokers 4 | **Event brokers** are middleware products that are used to facilitate, mediate and enrich the interactions of sources and handlers in event-driven computing. 5 | 6 | ### 1.2 Event-driven architecture 7 | **Event-driven architecture** (EDA) is inherently intermediated. Therefore, the intermediating role of event brokering is a definitional part of EDA. All implementations of event-driven applications must use some technology in the role of an event broker. 8 | 9 | 10 | The strategic role of event-driven computing in **digital business**, that strives for continuous awareness, intelligence and agility, creates a demand for event broker technology that is designed specifically for event-driven use cases. 11 | 12 | 13 | ### 1.4 Recommendations 14 | Application leaders engaged in modernizing their application architecture and infrastructure should: 15 | > 1. Build skills and technology for event-driven design to enable application designers to freely draw on traditional request-driven SOA or EDA capabilities as the business requires. 16 | 17 | > 2. Choose advanced event brokers for digital business innovation initiatives because of their specialized support for event processing, even if the previous-generation alternative pub-sub technology, such as MOMs or ESBs, is already used elsewhere in your organization. 18 | 19 | > 3. Include advanced event brokers when assembling your hybrid integration platform suite to support strategic event-driven solutions in your multiarchitecture application environment. 20 | 21 | > 4. Adopt event brokers with the understanding that the increasing maturity and standardization of technology over time will likely lead you to make changes to technology and its use patterns. 22 | 23 | ### 1.4 Benefits and Uses 24 | ``` 25 | IoT applications 26 | Data Integration and reconciliation 27 | Application-as-product extensibility 28 | Continuous intelligence 29 | Serverless functions 30 | Stream analytics 31 | ``` 32 | 33 | ### 1.5 Event Brokers in Context 34 | Every Event Brokers play a different role in different context。 35 | 36 | **Many middleware products can play the role of an event broker.** ESBs, MOMs, business process management (BPM) suites and Java EE application servers (via the embedded JMS) all typically have pub-sub capability and, therefore, can perform at least the minimum function of facilitating EDA interactions. However, few of these products were designed for event processing as their primary objective. ESBs center on integration and MOMs on delivering messages, while BPM suites manage workflows and application servers are a general-purpose application platform. 37 | 38 | With the increasing emphasis on event-driven computing in digital business, new middleware products are emerging with the primary purpose of supporting event processing. Two main categories of technology, offered together or separately, are part of this market: **the event brokers and the stream analytics engines** (Stream analytics is a modern evolution of complex event processing [CEP] technology and the two names sometimes are used interchangeably.) Stream analytics may act as either a source or a handler of event notifications (see Figure 2). 39 | ![image](https://www.gartner.com/resources/362900/362911/362911_0002.png?reprintKey=1-5D8UG66) 40 | 41 | All Event Notifications Arrive as Streams, Though Only Some Are Subject to Stream Analytics 42 | 43 | [more details](https://www.gartner.com/doc/reprints?id=1-5D8UG66&ct=180820&st=sb&first_name=mei&last_name=fen&work_email=269811655%40qq.com&company=we&job_title=CC&country=Canada&Email_OptIn=true&utm_medium=&utm_source=&utm_campaign=&utm_keyword=) 44 | 45 | 46 | ### 1.5 Serverless functions && EDA 47 | 48 | **Serverless functions** are principally designed to be **triggered by events and state changes** in data, apps, applications and other resources. The increasingly demanding use of serverless functions requires an elevated level of management, and **event broker technology** is where central management oversight is implemented. 49 | 50 | **Stream analytics** does not require the use of an event broker, However, a combination of event stream processing and an event broker elevates the use cases and design options for both. An event stream can be directed by an event broker to multiple subscribing analytics engines. Once the analytics work identifies a notable complex event, a notification is sent to an event broker to target the subscribing event handlers for all the necessary response work. 51 | 52 | 53 | 54 | 55 | 56 | 57 | ## 2. Serverless 58 | 59 | 60 | > Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform. By using these ideas, and related ones like single-page applications, such architectures remove much of the need for a traditional always-on server component. Serverless architectures may benefit from significantly reduced operational cost, complexity, and engineering lead time, at a cost of increased reliance on vendor dependencies and comparatively immature supporting services. 61 | 62 | 63 | 64 | Serverless(无服务器架构)指的是由开发者实现的服务端逻辑运行在无状态的计算容器中,它由事件触发, 完全被第三方管理,其业务层面的状态则被开发者使用的数据库和存储资源所记录。 65 | 66 | 67 | ![image](https://ws4.sinaimg.cn/large/006tNbRwgy1fv8y3128tfj30ja0dywf3.jpg) 68 | 69 | 70 | [无服务架构](https://aws.amazon.com/cn/blogs/china/iaas-faas-serverless/) 71 | 72 | 73 | 74 | 75 | 76 | --- 77 | 78 | 79 | ### 2.1 Serverless架构的优点 80 | 81 | - 降低运营成本: 82 | 83 | Serverless是非常简单的外包解决方案。它可以让您委托服务提供商管理服务器、数据库和应用程序甚至逻辑,否则您就不得不自己来维护。由于这个服务使用者的数量会非常庞大,于是就会产生规模经济效应。在降低成本上包含了两个方面,即基础设施的成本和人员(运营/开发)的成本。 84 | 85 | - 降低开发成本: 86 | 87 | IaaS和PaaS存在的前提是,服务器和操作系统管理可以商品化。Serverless作为另一种服务的结果是整个应用程序组件被商品化。 88 | 89 | 90 | - 扩展能力: 91 | 92 | Serverless架构一个显而易见的优点即“横向扩展是完全自动的、有弹性的、且由服务提供者所管理”。从基本的基础设施方面受益最大的好处是,您只需支付您所需要的计算能力。 93 | 94 | - 更简单的管理: 95 | 96 | Serverless架构明显比其他架构更简单。更少的组件,就意味着您的管理开销会更少。 97 | 98 | - “绿色”的计算: 99 | 100 | 按照《福布斯》杂志的统计,在商业和企业数据中心的典型服务器仅提供5%~15%的平均最大处理能力的输出。这无疑是一种资源的巨大浪费。随着Serverless架构的出现,让服务提供商提供我们的计算能力最大限度满足实时需求。这将使我们更有效地利用计算资源。 101 | 102 | 103 | 104 | ### 2.2 Serverless的架构范式 105 | 移动应用后台Serverless参考架构 106 | 107 | ![image](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/0118-faas-02.png) 108 | 109 | 110 | 实时文件处理Serverless参考架构 111 | 112 | 113 | ![image](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/0118-faas-03.png) 114 | 115 | 116 | Web应用Serverless参考架构 117 | 118 | ![image](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/0118-faas-04.png) 119 | 120 | 121 | 物联网应用后台参考架构 122 | 123 | ![image](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/0118-faas-05.png) 124 | 125 | 实时流处理Serverless参考架构 126 | 127 | ![image](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/0118-faas-06.png) 128 | 129 | ## 3. FAAS 130 | 131 | FaaS(Functions as a Service)函数即服务,FaaS是无服务器计算的一种形式,当前使用最广泛的是AWS的Lambada。 132 | 133 | 现在当大家讨论Serverless的时候首先想到的就是FaaS。FaaS本质上是一种事件驱动的由消息触发的服务,FaaS供应商一般会集成各种同步和异步的事件源,通过订阅这些事件源,可以突发或者定期的触发函数运行。 134 | 135 | ![image](https://ws3.sinaimg.cn/large/006tNbRwgy1fv8y3p7v04j30n60bowff.jpg) 136 | 137 | 138 | 传统的服务器端软件不同是经应用程序部署到拥有操作系统的虚拟机或者容器中,一般需要长时间驻留在操作系统中运行,而FaaS是直接将程序部署上到平台上即可,当有事件到来时触发执行,执行完了就可以卸载掉。 139 | 140 | 141 | 142 | ![image](https://ws1.sinaimg.cn/large/006tNbRwly1fv8y41b37rj30860bo74s.jpg) 143 | 144 | 145 | --- 146 | ## 3.1 Serverless && FaaS 147 | 148 | Function 可以理解为一个代码功能块,这个功能块具体包含多少功能,无法明确给出定义,但有一个明确的指标:冷启动时间需要在毫秒数量级。因为 FaaS 的本质上是以程序的快速启动来实现正真的按需运行,按需伸缩,以及高可用。Function 配合调度系统,就可以完全做到开发者对服务运行的实例无感,真 Serverless。 149 | 150 | 151 | Serverless 比 FaaS 的外延要广,FaaS 主要解决的是用户自定义的代码逻辑如何做到 Serverless,可以叫做 Serverless Compute,同时它也是事件驱动架构的一种,从一张图可以看出二者区别。 152 | 153 | ![image](https://www.phodal.com/static/media/uploads/serverless/mono-ms-sls.jpg) 154 | 155 | 156 | 157 | ![image](http://jolestar.com/images/faas/serverless-faas.png) 158 | 159 | ### 3.2 从云的发展来看 FaaS 160 | 161 | 第一阶段的云主要解决硬件资源(网络,计算,存储)的运维和供给问题,也就是 IaaS 云,可以理解成基于硬件资源的共享经济。IaaS 云的交付的主要是资源,接口以及控制台也是面向资源的,尽量以模拟物理机房环境来降低应用的迁移成本。而云发展到当前阶段来看,出现了两种需求: 162 | 163 | ###### 正真的按需计算 164 | >原来云的按需计算只是虚拟机维度的,按时间计费以及弹性伸缩,并不能正真做到按需计算,计算和内存资源都是预申请规划的,和服务的请求并发数并没有明确的关系,哪怕一段时间一个请求没有,资源还是依然占用。而 FaaS 可以做到按请求计费,不需要为等待付费,可以做到更高效的资源利用率。 165 | 166 | ###### 面向应用 167 | 168 | > 本质上用户对云的期望是应用的运行环境,并且最好是只让用户关心业务逻辑,而不需要关心,或者尽量少关心技术逻辑(比如监控,性能,弹性,高可用,日志追踪等)。这也是云原生应用(Cloud Native Application)这个概念提出的背景。 169 | 170 | 171 | ##### 云原生应用就是让渡一部分功能给云,以实现弹性,高可用,故障恢复,降低研发运维成本的应用 172 | 173 | 174 | 但 FaaS 给出来一个方案。就是应用只需要把包含自己业务逻辑的 Function 提交给云,其他的事情由云来完成。这样,云相当于直接接管了业务逻辑模块,然后其他的技术功能直接由云来提供,不依赖开发者在自己应用中引入标准化框架来实现。 175 | 176 | 177 | 178 | --- 179 | 180 | ## 4. Event Mesh && Service Mesh 181 | ### 4.1 Service Mesh 182 | 183 | Service Mesh被用作微服务的基础设施层,使通信变得更加灵活,可靠和快速。 它得到了谷歌、微软、IBM、红帽和 Pivotal 等行业巨头的推动,并且正在推出 Kubernetes、OpenShift 和 Pivotal Container Service(PKS)等平台和服务。 184 | 185 | 虽然 Service Mesh (服务网格)可以很好地支持同步 RESTful 和一般的<请求-回复>交互,但它不支持异步、事件驱动的交互,不适合将云原生微服务与遗留应用程序连接,也不适用于 IoT。 186 | 187 | 188 | 现代企业正在将事件驱动架构作为其数字化转型的一部分,每个事件驱动型的企业都需要一个中枢神经系统来快速、可靠和安全地将事件从它们发生的地方发送到它们需要去的地方。 189 | 190 | 这个中枢神经系统可以被视为 Event Mesh(事件网格) 191 | 192 | 事件网格作为服务网格的补充,可以做为应用程序的连接层,以提供企业实现其数字化转型目标所需的全套应用程序间通信模式。 193 | 194 | ![image](https://ws4.sinaimg.cn/large/006tNbRwly1fxmu7vq7crj30kh0cajsy.jpg) 195 | 196 | ### 4.2 Event Mesh 197 | 198 | 事件网格对于事件驱动的应用程序,就好比是服务网格对于 RESTful 应用程序:一个架构层,无论在哪里部署这些应用程序(非云、公有云或者私有云),都可以动态路由某个应用程序的事件并使其被其他应用程序所接收。 事件网格由内部连通的 Event broker(事件代理)网络来创建和启用。 199 | 200 | 201 | ### 4.3 Event Mesh vs. Service Mesh 202 | 203 | 事件网格可以做为服务网格的补充。 事件网格和服务网格类似,它们可以在应用程序之间实现更好的通信,并允许应用程序通过将某些功能放在网络层和应用程序层之间,这样我们可以更多地关注业务逻辑。 但是,相比之下,也有一些重要的区别: 204 | 205 | 服务网格连接云环境中的微服务,例如 Kubernetes,Amazon ECS、Google Kubernetes Engine、IBM Cloud 和 Alibaba; 206 | 事件网格不仅连接微服务(容器化或其他),还连接遗留的应用程序、云原生服务以及可在云和非云环境中运行的各种设备和数据源/接收端。 事件网格可以将任何事件源连接到任何事件处理程序,无论它们在何处部署。 207 | 208 | 209 | 210 | ### 4.4 Event Mesh 的特点 211 | 事件网格的定义有三个显著特征。 事件网格是: 212 | 213 | > 1. 由内部连通的 Event Broker 形成的组合 214 | > 2. 与相关环境无关 215 | > 3. 动态性 216 | 217 | 事件网格的`动态性`可能是其最重要的属性。 所谓动态,指的是它能够动态地了解哪些事件将被路由到哪些消费者应用程序,然后在事件发生时实时路由这些事件,无论生产者和消费者在哪里被附加到网格, 而且无需配置事件路由。 我们应该让事件网格负责这些,而不是开发人员。 218 | 219 | 220 | ### 4.5 为什么企业需要 Event Mesh? 221 | 简而言之,事件网格支持以下使用场景: 222 | 223 | > - 连接和编排微服务 224 | > - 将事件从内部部署推送到云应用程序或服务(混合云) 225 | > - 跨 LOB(line-of-business)启用“数据即服务” 226 | > - 实现与后端系统的物联网连接 227 | 228 | ### 4.6 事件网格 229 | 230 | 使企业能够支持事件驱动的体系结构,从最小的微服务部署,到以易管理、健壮、安全和架构良好的方式将应用程序扩展到混合云。 它提供了动态和全部实时地集成遗留应用程序、数据存储、现代微服务、SaaS、物联网和移动设备的能力。 事件网格为应用程序开发人员和架构师提供了构建和部署分布式事件驱动应用程序的基础,无论他们需要在何处构建和部署。 231 | 232 | 233 | 234 | --- 235 | KeyWord 236 | 237 | --- 238 | 参考: 239 | 240 | - [从IaaS到FaaS—— Serverless架构的前世今生 241 | ](https://aws.amazon.com/cn/blogs/china/iaas-faas-serverless/) 242 | - [martinfowler](https://martinfowler.com/articles/serverless.html) 243 | - [Evolution of Server Computing: VMs to Containers to Serverless — Which to Use When? 244 | ](https://www.gartner.com/doc/3749163/evolution-server-computing-vms-containers) 245 | - [Snafu: Function-as-a-Service (FaaS) Runtime 246 | Design and Implementation](https://arxiv.org/pdf/1703.07562.pdf) 247 | - [FaaS,未来的后端服务开发之道 248 | ](https://www.jianshu.com/p/6e86c42f85bd) 249 | - [thread-goroutine-actor](http://jolestar.com/parallel-programming-model-thread-goroutine-actor/) 250 | - [microservice-with-service-mesh-at-ant-financial](http://www.servicemesher.com/blog/microservice-with-service-mesh-at-ant-financial/) 251 | - [solace-event-mesh](https://solace.com/blog/event-mesh) 252 | - [gartner](https://www.gartner.com/doc/reprints?id=1-5D8UG66&ct=180820&st=sb&first_name=mei&last_name=fen&work_email=269811655%40qq.com&company=we&job_title=CC&country=Canada&Email_OptIn=true&utm_medium=&utm_source=&utm_campaign=&utm_keyword=) 253 | 254 | 255 | --- 256 | ### WOSC18 257 | - [NumPyWren](https://www.serverlesscomputing.org/wosc3/presentations/eric-jonas-IEEE-Cloud-Serverless-Workshop-July-2018-Jonas.pdf) 258 | - [How Microservices and Serverless Computing 259 | Enable the Next Gen of Machine Intelligence](https://www.serverlesscomputing.org/wosc3/presentations/algorithmia-OS-for-AI-WoSC.pdf) 260 | - [Conquering Serverless](https://www.serverlesscomputing.org/wosc3/presentations/stackery-ConqueringServerless.pdf) 261 | - [Building and Teaching a Complete Serverless Solution](https://www.serverlesscomputing.org/wosc3/presentations/sparqtv-wosc2018-draft.pdf) 262 | - [Challenges for Serverless Native 263 | Cloud Applications](https://www.serverlesscomputing.org/wosc3/presentations/ben-kehoe-2018_wosc.pdf) 264 | - [Evaluation of Production Serverless 265 | Computing Environments](https://www.serverlesscomputing.org/wosc3/presentations/p1-wosc-july02-hlee.pdf) 266 | - [Serverless Data Analytics with Flint](https://www.serverlesscomputing.org/wosc3/presentations/p2-flint_slides_v2.pdf) 267 | - [Making Serverless 268 | Computing More Serverless](https://www.serverlesscomputing.org/wosc3/presentations/p3-wosc3-rozner.pdf) 269 | - [Challenges for Scheduling Scientific 270 | Workflows on Cloud Functions](https://www.serverlesscomputing.org/wosc3/presentations/p4-cloud-functions-scheduling-wosc-v3.pdf) 271 | 272 | 273 | Build skills and technology for event-driven design 274 | event brokers 275 | assembling your hybrid integration platform 276 | 277 | standardization of technology 278 | 279 | 280 | ## Benefits and Uses 281 | 282 | The role of an event broker is central to facilitating event-driven computing in digital business. 283 | 284 | - IoT applications 285 | - Data Integration and reconciliation 286 | - Application-as-product extensibility 287 | - Continuous intelligence 288 | - Serverless functions 289 | - Stream analytics 290 | 291 | 292 | --- 293 | 294 | Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform. By using these ideas, and related ones like single-page applications, such architectures remove much of the need for a traditional always-on server component.Serverless architectures may benefit from significantly reduced operational cost, complexity, and engineering lead time, at a cost of increased reliance on vendor dependencies and comparatively immature supporting services. 295 | 296 | – Amazon Lambda 297 | – Microsoft Azure Functions 298 | – Google Functions 299 | – IBM Functions powered by Apache OpenWhisk 300 | – w.r.t CPU, File I/O and network intensive workloads 301 | 302 | --- 303 | ### martinfowler 304 | 305 | - [Serverless](https://martinfowler.com/articles/serverless.html) 306 | 307 | 308 | --- 309 | ### WOSC18 310 | - [NumPyWren](https://www.serverlesscomputing.org/wosc3/presentations/eric-jonas-IEEE-Cloud-Serverless-Workshop-July-2018-Jonas.pdf) 311 | - [How Microservices and Serverless Computing 312 | Enable the Next Gen of Machine Intelligence](https://www.serverlesscomputing.org/wosc3/presentations/algorithmia-OS-for-AI-WoSC.pdf) 313 | - [Conquering Serverless](https://www.serverlesscomputing.org/wosc3/presentations/stackery-ConqueringServerless.pdf) 314 | - [Building and Teaching a Complete Serverless Solution](https://www.serverlesscomputing.org/wosc3/presentations/sparqtv-wosc2018-draft.pdf) 315 | - [Challenges for Serverless Native 316 | Cloud Applications](https://www.serverlesscomputing.org/wosc3/presentations/ben-kehoe-2018_wosc.pdf) 317 | - [Evaluation of Production Serverless 318 | Computing Environments](https://www.serverlesscomputing.org/wosc3/presentations/p1-wosc-july02-hlee.pdf) 319 | - [Serverless Data Analytics with Flint](https://www.serverlesscomputing.org/wosc3/presentations/p2-flint_slides_v2.pdf) 320 | - [Making Serverless 321 | Computing More Serverless](https://www.serverlesscomputing.org/wosc3/presentations/p3-wosc3-rozner.pdf) 322 | - [Challenges for Scheduling Scientific 323 | Workflows on Cloud Functions](https://www.serverlesscomputing.org/wosc3/presentations/p4-cloud-functions-scheduling-wosc-v3.pdf) 324 | -------------------------------------------------------------------------------- /当我在看EDA时候.md: -------------------------------------------------------------------------------- 1 | ## 知识准备 2 | 关键词解释: 3 | 1. iBPM:代表智能业务流程管理(Intelligent Business Process Management) 4 | 2. SOA:面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。 5 | 3. CEP:复杂事件处理 (CEP) 处理同时发生的不同事件,以确定这些事件对应的操作。事件通道中的事件可以有不同的事件类型,并且可以长期发生。可以根据内容、时间或位置来关联事件。因此,CEP 通常用于检测异常、风险,甚至业务机会,旨在利用相比传统报告解决方案更具现时性的信息的优势,最终在竞争中占据上风。 6 | 4. EDA:一个事件驱动框架(EDA)定义了一个设计和实现一个应用系统的方法学,在这个系统里事件可传输于松散耦合的组件和服务之间。一个事件驱动系统典型地由事件消费者和事件产生者组成。事件消费者向事件管理器订阅事件,事件产生者向事件管理器发布事件。当事件管理器从事件产生者那接收到一个事件时,事件管理把这个事件转送给相应的事件消费者。如果这个事件消费者是不可用的,事件管理者将保留这个事件,一段间隔之后再次转送该事件消费者。这种事件传送方法在基于消息的系统里就是:储存(store)和转送(forward)。 7 | 5. ESP:在事件流处理 (ESP) 中,除了“相关”事件以外,“通常的”事件(如所有一般指令或 RFID 事件)也会发布到事件通道中。这对事件处理提出了更高的要求,同时也提供了更多评估选项。 8 | 6. SEP:在简单事件处理 (SEP) 中,只有“相关”事件才会被放入事件通道中进行处理。比如“XY 类别的汽车已售罄”或“冬季轮胎库存紧张”。这非常类似于基于消息的系统。处理逻辑评估事件类型和内容,然后相应地做出反应。 9 | 7. MDM:MDM 提供通用组件(或服务)以确保数据维护和分发的一致性。 10 | 8. FP 11 | 9. FRP 12 | 10.RP 13 | 11.ESB:Gartner 于 2002 年创造了术语“企业服务总线”,分析师 Roy Schulte 进一步引入这个术语来描述当时市场上的一类软件产品。10 年后,关于 EBS 到底是什么或者它应该提供什么依然没有达成共识。根据制造商和来源的不同,有很多不同的定义。其中,ESB 的定义包括: 14 | “一种集成架构样式,支持提供者和服务用户之间通过由各种点对点连接构成的公共通信总线进行通信” 15 | “企业用来集成应用程序环境中服务的基础架构。” 16 | “一种架构模式,使用面向服务支持异构环境之间的互操作性。” 17 | 11. Faas 18 | 12. serverless 19 | 20 | 21 | --- 22 | ## 一、EDA 23 | ### 1.1 EDA定义 24 | 25 | Gartner在2003年引入了一个新术语事件驱动架构(Event Driven Architecture,EDA), 主要用于描述一种基于事件的范例。EDA 是一种用于进行设计和实现应用和系统的方法—在这些应用和系统里, 事件所触发的消息可以在独立的、非耦合的组件和服务之间传递,这些模块彼此并不知晓对方。这些应用程序中的EDA极大地改进了企业或政府响应不同的、表面上毫无关联事件的能力。通过提供瞬时过滤、聚合和关联事件的能力,EDA可以快速地检测出事件并判断它的类型,从而帮助组织机构快速、恰当地响应和处理这些事件。通常事件可以采用发布/订阅机制。 26 | 27 | ### 1.2 事件驱动架构概述 28 | 29 | 一个事件驱动框架(EDA)定义了一个设计和实现一个应用系统的方法学,在这个系统里事件可传输于松散耦合的组件和服务之间。一个事件驱动系统典型地由事件消费者和事件产生者组成。事件消费者向事件管理器订阅事件,事件产生者向事件管理器发布事件。当事件管理器从事件产生者那接收到一个事件时,事件管理把这个事件转送给相应的事件消费者。如果这个事件消费者是不可用的,事件管理者将保留这个事件,一段间隔之后再次转送该事件消费者。这种事件传送方法在基于消息的系统里就是:储存(store)和转送(forward)。 30 | 31 | 构建一个包含事件驱动构架的应用程序和系统,会使这些应用程序和系统响应更灵敏,因为事件驱动的系统更适合应用在不可预知的和异步的环境里。 32 | 33 | 事件驱动架构在具体实现中是指由一系列相关组件构成的应用,而组件之间通过事件机制完成一定的业务功能。由于在一个EDA系统中各个组件都只专注于处理输入的消息与发布输出的消息,因而EDA系统能够更有加效地对管道化(pipelined)的、由多软件模块链接而成的并发事件流(concurrent processing of events)进行处理。 34 | 35 | ### 1.3 EDA特点 36 | EDA系统中各组件以异步方式响应事件,在本质上是可以并行的,因而在政府部门的电子政务应用中具有极大的优势。其具备以下特点: 37 | 38 | ◆ 并发执行 39 | 40 | ◆ 事件触发/数据触发/时间规则触发 41 | 42 | ◆ 实时/增量响应 43 | 44 | ◆ 分布式事件系统处理 45 | 46 | 上述特点能很好地满足政府部门应用需求,如跨部门的应急联动系统或联合监管协同服务等应用。 47 | 48 | 从目前情况来看,EDA系统还只是处理简单事件的系统,对于复杂事件的处理还有待进一步的研究。但是,EDA仍然能作为SOA系统的一个有效补充,弥补SOA系统的一些不足,如实时响应度不够。 49 | 50 | ### 1.4 事件驱动架构优势 51 | 52 | 事件驱动设计和开发所提供的优势如下所示: 53 | 54 | > ◆ EDA提高了对不断变化的业务需求的响应,最大限度地减少了对现有业务应用的影响,也常消除了对新打包应用的需要。如果采用特有的粗颗粒服务模型可以基于业务目标快速确定可控的业务变更,并直接、迅速、有效地实施变更以达到业务敏捷性和完整性。 55 | 56 | > ◆ 可以更容易开发和维护大规模分布式应用程序和不可预知的服务或异步服务; 57 | 58 | > ◆ 可以很容易,低成本地集成、再集成、再配置新的和已存在的应用程序和服务。 59 | 60 | > ◆ 促进远程组件和服务的再使用,拥有一个更灵敏、没有Bug的开发环境。 61 | 62 | 从时间维度来看EDA的优势: 63 | 64 | > ◆ 短期利益:更容易定制,因为设计对动态处理有更好的响应; 65 | 66 | > ◆ 长期利益:系统和组织的状态变得更精准,对实时变化的响应接近于同步。 67 | 68 | 69 | 70 | ### 1.5 EDA和SOA之间的关系: 71 | 72 | SOA和EDA是平等和互补的。所以,我不认同那些努力传播SOA的同学们所说的“EDA只是SOA的一个子集”的论断。一个更广泛的事件驱动架构概念,不仅是超越事件驱动SOA的,还应该包括实时信息流和分析,以及复杂事件处理。 73 | 74 | 当EDA认为事件是系统中最重要的组成时,你最好注意那些组件或者服务,以及组件之间的‘通道’” 75 | 76 | 与Request/Response系统不同的是,要求请求者必须明确发送请求信息,而事件驱动架构提供一个机制去动态响应事件。在一个EDA系统里,事件产生者发布事件,事件消费者接受事件。 77 | 78 | 业务系统可以从SOA和EDA中受益匪浅,因为事件发生时EDA系统能触发事件消费者,SOA服务可以快速地从相同的消费者中访问、查询。系统要求有最高的响应性,当事件被触发时这个系统必须能快速决定必须的动作。到事件结束,事件应该被发布和消费,而且事件要穿越SOA所有的边界,包括整个体系结构和物理层。 79 | 80 | 系统要有最高的响应性,当事件触发时这个系统必须能快速决定必须的动作。到事件结束,事件应该被发布和消费,而且事件要穿越SOA所有的边界,包括整个体系结构和物理层。 81 | 82 | ### 1.6 ESB连接EDA和SOA 83 | 企业服务总线(Enterprise Service Bus,ESB)在异类平台和环境间建立联系,充当允许不同应用程序进程之间进行通信的中间层。部署到企业服务总线的服务可以由使用者或事件触发。它同时支持同步方式和异步方式,可促进一个或多个参与者之间的交互。因此 ESB 可提供 SOA 和 EDA 范例的所有功能。“ESB提供了消息的传输,格式的转换等关键功能,为服务的请求者和服务提供者之间架设了沟通的桥梁,是企业应用基础架构的粘合剂。” 甲骨文公司大中华区高级技术经理黄建勇说。 84 | 85 | 企业服务总线可连接各个异类节点并作为中介传递其间的所有通信和交互,这些节点可分散在面向服务的体系结构(同步一对一方法)和事件驱动的体系结构(异步多对多方法)中。ESB 是目前处理集成挑战的最有效方法,是可提供最大业务灵活性和不同应用程序间的高效连接技术解决方案。 86 | 87 | EDA应用在很多ESB(企业服务总线)产品中,比如FiornaoESB中间件产品支持同步、异步和请求响应事件,事件处理和传输实用不同的技术例如JMS,HTTP,电子邮件和基于XML的RPC等。比如“政府网上监察系统”通过对被监察对象(系统)数据的实时采集,通过EDA技术的事件触发,事件过滤,实现对违规、违法、越权行政、超时限行政等问题进行通知和督办等。 88 | 89 | ### 1.7 EDA应用方向 90 | 91 | 事件驱动架构(EDA)是分布式应用程序的普遍架构形式,非常典型的是:分布式应用程序都被设计成为模块化的、封装的、可共享事件服务的组件。能够通过应用程序、适配器以及无入侵性的代理操作来创建这些服务。 92 | 93 | 由于EDA的特点,在金融贸易、能源贸易、电信以及欺诈检测这些行业中,一直都在采用事件驱动架构(EDA)技术。近期在我国政府的电子政务建设中 94 | 95 | 利用EDA分布式处理架构的优势构建共享交换平台,实现跨部门、跨平台、跨应用系统的政务信息资源的共享与交换,并对政府应急系统和跨委办局之间的业务协同办公提供支撑和保障。 96 | 97 | 98 | 99 | [EDA](http://tech.it168.com/a2009/0313/268/000000268470.shtml) 100 | 101 | [Martin Fowler](https://martinfowler.com/articles/201701-event-driven.html) 102 | 103 | 104 | --- 105 | 106 | ## 二、响应式编程和响应式系统(EP&&ERP) 107 | 响应式技术目前成功的标志之一是“响应式reactive”成为了一个热词,并且跟一些不同的事物与人联系在了一起——常常伴随着像“流streaming”、“轻量级lightweight”和“实时real-time”这样的词。 108 | ### 2.1 FRP 109 | - [FRP定义](http://conal.net/papers/icfp97/) 110 | 111 | 112 | ### 2.2 响应式编程Reactive programming, 113 | 114 | 不要把它跟函数响应式编程混淆了,它是异步编程下的一个子集,也是一种范式,在这种范式下,由新信息的有效性availability推动逻辑的前进,而不是让一条执行线程a thread-of-execution去推动控制流control flow。 115 | 116 | 117 | 响应式编程一般是事件驱动event-driven,相比之下,响应式系统则是消息驱动message-driven的 118 | 119 | 120 | 响应式编程的基本好处是:提高多核和多 CPU 硬件的计算资源利用率;根据阿姆达尔定律以及引申的 Günther 的通用可伸缩性定律Günther’s Universal Scalability Law 脚注3 ,通过减少序列化点serialization points来提高性能。 121 | 122 | 另一个好处是开发者生产效率,传统的编程范式都尽力想提供一个简单直接的可持续的方法来处理异步非阻塞式计算和 I/O。在响应式编程中,因活动(active)组件之间通常不需要明确的协作,从而也就解决了其中大部分的挑战。 123 | 124 | 响应式编程真正的发光点在于组件的创建跟工作流的组合。为了在异步执行上取得最大的优势,把 反压back-pressure加进来是很重要,这样能避免过度使用,或者确切地说,避免无限度的消耗资源。 125 | 126 | 127 | ### 2.4 事件驱动 && 消息驱动 128 | 响应式编程——专注于短时间的数据流链条上的计算——因此倾向于事件驱动,而响应式系统——关注于通过分布式系统的通信和协作所得到的弹性和韧性——则是消息驱动的 脚注4 (或者称之为 消息式messaging 的)。 129 | 130 | 一个拥有长期存活的可寻址long-lived addressable组件的消息驱动系统跟一个事件驱动的数据流驱动模型的不同在于,消息具有固定的导向,而事件则没有。消息会有明确的(一个)去向,而事件则只是一段等着被观察observe的信息。另外,消息式messaging更适用于异步,因为消息的发送与接收和发送者和接收者是分离的。 131 | 132 | 133 | >一条消息就是一则被送往一个明确目的地的数据。一个事件则是达到某个给定状态的组件发出的一个信号。在一个消息驱动系统中,可寻址到的接收者等待消息的到来然后响应它,否则保持休眠状态。在一个事件驱动系统中,通知的监听者被绑定到消息源上,这样当消息被发出时它就会被调用。这意味着一个事件驱动系统专注于可寻址的事件源而消息驱动系统专注于可寻址的接收者。 134 | 135 | 136 | 137 | ### 2.5 响应式系统 138 | 响应式系统的基石是消息传递message-passing,消息传递为两个组件之间创建一条暂时的边界,使得它们能够在 时间 上分离——实现并发性——和 空间space ——实现分布式distribution与移动性mobility。这种分离是两个组件完全 隔离isolation以及实现 弹性resilience和 韧性elasticity基础的必需条件。 139 | 140 | 141 | 142 | ### 2.6 响应式系统&&响应式编程 143 | 144 | 响应式编程是一种管理内部逻辑internal logic和数据流转换dataflow transformation的好技术,在本地的组件中,做为一种优化代码清晰度、性能以及资源利用率的方法。响应式系统,是一组架构上的原则,旨在强调分布式信息交流并为我们提供一种处理分布式系统弹性与韧性的工具。 145 | 146 | 响应式编程是一个非常有用的实现技术,可以用在响应式架构当中。但是记住这只能帮助管理一部分:异步且非阻塞执行下的数据流管理——通常只在单个结点或服务中。当有多个结点时,就需要开始认真地考虑像数据一致性data consistency、跨结点沟通cross-node communication、协调coordination、版本控制versioning、编制orchestration、错误管理failure management、关注与责任concerns and responsibilities分离等等的东西——也即是:系统架构。 147 | 148 | 149 | 150 | --- 151 | ## 三、CEP 152 | 153 | ### 3.1 关键概念 154 | 事件指在业务里发生的事情,包括业务活动、流程状态、网络或IT条件,或者其他任何东西。很多事件只要能够识别出来就可以进行处理,通常会伴随着发送警报。当无法可靠处理单个事件而必须在上下文里分析时,就会使用CEP。几乎所有场景里,CEP分析都要求`事件`能够`实时`关联,并且要求带有准确时间戳的一定格式。 155 | 156 | CEP应用大致分为两大类:`事件关联和根本原因分`析。通常来说,事件关联用来识别不是单个事件,而是多个事件组合起来触发的条件. 157 | > 比如“如果你打喷嚏并且发烧了,那么你感冒了。”根本原因分析用来解释一系列事件—通常是错误—的底层原因,确保补救措施并不仅仅针对症状,而是能够真正解决问题。 158 | 159 | 所有CEP都应该是实时的,或者和事件同时发生,但是,当然这里的同时发生意味着很多种情况。CEP处理的关系越复杂,就越难保证实时性。 160 | 161 | ### 3.2 从事件驱动编程(Event-driven Programming)开始 162 | 如果你写过GUI程序,对事件处理一定不陌生。事实上,事件驱动编程已经成为一种`设计模式`。大多数的GUI库都会采用这一模式。 163 | 164 | > 简单的说,事件驱动模式包括三个参与者:事件产生者,事件分发器和事件处理器。 165 | 166 | - 事件产生者(Events Generator)决定是否需要产生事件。比如,GUI上的每个组件都是一个事件产生者,可以根据用户操作产生鼠标事件或者键盘事件。 167 | 168 | - 事件分发器(Events Dispatcher)收集所有事件产生者发出的事件放入事件队列(Events Queue),并根据事件的类型将事件分发给已经注册的事件处理器。事件分发器通常由GUI框架实现。 169 | 170 | - 事件处理器(Events Handler)根据接收到的事件进行处理,需要GUI框架的使用者自行编写。 171 | 172 | 事件驱动编程的核心价值在于:程序的执行流程不是预先定义好的,而是由程序的使用者决定的。这将极大增强程序的`交互性`。 173 | 174 | 就好像DVD与RPG游戏的区别:前者的剧情是设定好的,你只能进行开始、暂停、快进、回退等有限的交互;后者可以决定主角的行为从而影响故事的结局。 175 | 176 | ### 3.3 事件驱动业务(Event-driven Business) 177 | 代码的世界不可能是现实世界的完整镜像,但一定是对现实世界的某种抽象,这种抽象能够简化代码世界中对问题的分析和处理。 同时,这种抽象还可以反向映射到现实世界,为我们解决现实问题提供思路。 178 | 179 | 现代企业生存的外部环境处于剧烈的变化之中,“敏捷企业”已经成为生存之道,而事件驱动业务是敏捷企业的一个基本要求。 180 | 181 | 事件驱动业务(Event-driven Business),是在连续 的业务过程中进行决策的一种业务`管理方式`,即根据`不同时点`上出现的一系列`事件触发相关的任`务,并调度可用的`资源执行任务`。 如果说`事件驱动编程`能够为软件带来更灵活的交互性和强大的功能,那么企业中的事件驱动业务能够`大幅度提高业务的效率和灵活性`。 182 | 183 | 事件驱动业务依托于比较成熟的信息化建设。各个业务应用系统在产生连续`不断的数据流`的同时,根据定义好的条件产生一些`业务事件`,按照策略对这些业务`事件进行分析处理`,`触发`新的业务事件或者业务流程,即实现了业务的`事件驱动`。 184 | 185 | 从上面的描述可以看出,事件驱动业务要求能够快速(毫秒级)、不间断的处理连续、海量的数据,具备灵活的规则或策略设置,从而具备迅速识别、捕获、响应实时业务数据的能力。 而传统的企业IT架构通常采用: 186 | 187 | 在业务应用系统中处理业务操作 188 | 遵循固定的业务流程(Business Process)处理跨系统事务,并且这些流程很少变化基于数据仓库进行海量数据的存储及事后分析 189 | 这种IT架构远远达不到事件驱动业务的要求。 190 | 191 | 事件驱动业务能够应用的业务领域很多,凡是需要快速处理`连续性数`据、需要能够`灵活制定策略`的业务,都可以采用`事件驱动的业务模式`。如证券行业常见的风险分析预警(事前及事中风控)、投资决策(程序化交易)、经纪人绩效计算等。 192 | 193 | 194 | ### 3.2.1 业务事件处理的几个层次 195 | 196 | 其实在传统的IT架构中,我们已经实现了业务事件的处理。比如在传统的业务应用系统中,我们通常将业务数据存储在数据库中,通过应用系统的操作界面由人工发现和处理业务事件。 197 | 198 | 这样的处理方式存在两个不足,一是速度慢,二是对于复杂的情况只靠人脑难以处理。于是有了两个技术方向: 199 | 200 | 消息队列(MQ) 对于速度慢的解决办法是用机器代替人工,为了在多个系统之间传递消息,发展出了消息队列(MQ)的技术 201 | 商业智能(BI) 为了应对复杂性,通过数据仓库将数据整合到一起,并用专门的工具在数据模型的基础上进行分析 202 | 但是上述两个方向是正交的:MQ不适合处理复杂性,而BI主要适应于对结构化的历史数据的分析,无法处理“现在”的情况。 203 | 204 | 205 | ### 3.4 CEP:鱼与熊掌可以兼得 206 | CEP(Complex Event Processing)的出现解决了上述两个方面的问题,在`实时性`和`复杂性`方面都得到了很好的解决。 207 | 208 | #### 3.4.1 处理数据流 209 | 不管是单独的应用系统,还是数据仓库,都是先将数据存储到数据库/数据仓库,然后再处理或查询。 而CEP与MQ类似的将数据看作是`数据流` 。在`连续数据的快速移动过程中进行分析处理`。 这样的方式不需要很大的数据加载,完全可以在内存中进行,从而能够快速产生结果。 210 | 211 | #### 3.4.2 处理复杂性 212 | 业务事件可能很复杂,在各种不同的数据流中源源不断产生各种类型的事件。需要对这些业务事件进行复杂的计算,如过滤、关联、聚合等,同时还需要考虑这些也是事件出现的时间序列。 最终才能产生有`意义的事件`,或`触发业务流程`。同时,这些计算的规则可能还会经常变化。 213 | 214 | 这一类的问题通常通过基于规则的推理机(即规则引擎)来实现。 215 | 216 | 综上所述,CEP在逻辑上应该包括: 217 | 218 | 1. 事件发生器 通过应用系统、文件系统、数据库、互联网、人工、以及传感器产生事件 219 | 2. 事件处理器 模式的匹配、验证和改进,路由,转换以及编排 220 | 3. 事件消费者 与事件发生器类似,也可以是应用系统、文件系统、数据库、互联网、人工界面等 221 | 222 | 223 | ### 3.5 CEP的三个基本模型及其特性,以及CEP的限制 224 | 225 | CEP的最简单方案是`触发或者阈值激活处理`。该模型里,事件要么直接导致一些操作的发生,要么是当事件达到某个阈值时会执行某个操作。CEP能够在从源到目的地的事件流里引入事件处理,比如在线事务处理,因为生成的延时很小。虽然触发或阈值CEP能够通过单个类型事件实现,但是也可以使用多个不同权重的不同事件来提供对条件更为深入的理解。 226 | 227 | 第二种模型是`上下文模型`,该模型假定一个事件或者事件集在某个特定的上下文里才有意义,因此需要维护这个上下文。可以通过模式匹配来完成,意味着查找满足某个模式的特定事件集,或者当事件改变某个显式上下文或状态时通过状态事件处理,随后在上下文理解事件。后一种方案很广泛地用于网络管理,这里上下文示例可能包括初始化,激活或者错误。 228 | 229 | 对于更为复杂的CEP,可以使用`级联分析模型`,这里的事件流包括使用某个CEP模型处理的一种或者多种类型的事件。它们并不是直接采取操作加以处理,而是生成其他事件或者事件上下文,随后注入CEP的其他阶段,直到能够最终决定采取什么操作。 230 | 231 | 232 | 综上所述,需要关注的点是: 233 | 1. 触发或者阈值激活处理 234 | 2. 上下文模型 235 | 3. 级联分析模型 236 | 237 | 238 | --- 239 | 240 | ## 四、iBPM 241 | iBPM 代表智能业务流程管理(Intelligent Business Process Management)。Gartner 认为iBPM在 BPM 的基础上增强了复杂事件处理(CEP)、智能机器人和云服务的能力,并在案例管理以及流程协调能力上更为卓越。 242 | 243 | `Gartner`的`Jim Sinur`最早提出了“iBPM”的概念。实际上,当业务流程管理系统(BPMS)与其他智能工具融合, iBPM便应运而生。这些智能工具包括机器学习、云服务、移动社交、复杂事件处理(CEP)、物联网集成、业务活动监控(BAM)。 244 | 245 | 把事件技术跟操作联系在一起,让分析结果跟应用集成及有用的商业活动关联,这些对于业务流程管理(BPM)的实践者来说是重要的。 246 | 247 | ### 4.1 特点 248 | 249 | iBPM有以下一些特点: 250 | 251 | 1. 更智能的自动化 252 | 253 | 更智能的路由,由流程机器人自动完成流程工作; 254 | 255 | 2. 更智能的移动工作 256 | 257 | 云服务,支持任何地方的流程工作; 258 | 259 | 3. 更智能实时的分析能力 260 | 261 | 复杂事件处理(CEP)能力; 262 | 263 | 264 | ### 4.2 iBPM与BPM的区别 265 | 266 | 267 | BPM是以规范标准的方式对业务流程进行建模以及执行的一组工具,而iBPM 是BPM的智能提升。从流程发现、设计、建模、 执行、监控以及分析优化的流程全生命周期的各个阶段,融合了人工智能、复杂事件处理、云服务和移动技术。 268 | 269 | 270 | 271 | 272 | ### 4.3 iBPM 特点 273 | 根据Pega System,iBPM中的智能(i)体现在以下几个方面: 274 | 275 | 276 | - 动态案例管理: 277 | >iBPM支持传统的预设计划和结构化的BPM流程,也支持创建关联知识工作者的动态流程案例。这些动态流程案例反映出融合社交、协作、响应式的新型工作模式,包括异常处理。动态案例可以由多层级的任务组成,也可以响应或触发事务。 278 | 279 | - 社交iBPM: 280 | > iBPM在流程生命周期的各阶段融入社交工具。最重要的是,iBPM提供了社交网络在规则协作下的应用场景。 281 | - 移动iBPM:iBPM允许组织通过移动设备无缝启动和完成端到端的自动化流程工作。流程状态、流程工作和通过移动流程合作的即时性使得全新的移动工作成为可能。 282 | 283 | - 云iBPM: 284 | 285 | > 通过云端的iBPM平台,可以安全建立企业应用程序,也就是iBPM平台即服务(PaaS); 而最终BPM解决方案构建和部署后,iBPM成为可以在云上执行或运行的服务:iBPM软件即服务(SaaS); 286 | 287 | - iBPM中的业务规则: 288 | > 业务规则实现业务决策逻辑和业务策略,这些规则驱动iBPM的解决方案。业务规则有许多类别和类型,如决策树、决策表、约束和表达式。业务规则的重点是使业务逻辑尽可能接近业务,而不必担心执行时间、执行方法或执行顺序。业务规则是声明式的,可以使用预测建模技术来检测业务模式,然后在iBPM的场景中调用或操作已发现的规则; 289 | 290 | - iBPM用于实时决策的分析和自适应: 291 | 292 | > 行业中最重要的趋势之一是数据科学的出现,特别是大数据分析。预测分析可以通过解开隐藏在大量数字信息中的规律,为组织带来实实在在的好处。 iBPM通过预测和自适应(自学习)分析,使得探寻某些决策具有可操作性。在iBPM中,可执行模型中用以挖掘的数据来源和类型多种多样,涵盖社交网络、事务数据和数据仓库。iBPM运用预测和自适应数据分析模型,在各种动态案例交互中提供更智能化的执行方案。 293 | 294 | BPM解决方案是动态的、社会化的、移动的、规则驱动和适应性的。这些解决方案可以不断地分析、学习和适应外部事件,以及三方成员和参与者的行为。 iBPM为适应性企业提供了平台、解决方案、最佳实践、方法和管理方式。 295 | 296 | 297 | iBPM的研究和技术使得“适应性企业”在商业环境中脱颖而出。通过智能业务流程管理,自适应的企业不断将其经营目标的政策和业务流程完全透明,使得业务流程管理的能见度更高、控制力更强。在未来的商业环境中,适应性企业在应对变化时变得更灵活和主动。毕竟,商业中唯一不变的就是改变! 298 | 299 | --- 300 | ## 五、MDM 301 | 302 | ### 5.1 MDM 的作用 303 | 304 | MDM 的作用是组织如何处理公司实施其业务流程所需的主数据。 305 | 306 | 主数据管理 — 主数据管理 (MDM) 是旨在确保主数据质量的管理活动。其目的是保证主数据对象适用于公司所有增值流程。MDM 包括所有必要的操作和控制流程,这些流程包含质量保证定义,并保证对主数据对象实施维护和管理。此外,MDM 还提供 IT 组件来映射这个过程。因此,MDM 起着支撑作用,并以隐含的方式从两个方向帮助提高附加值。首先是数据质量管理不断提高主数据的数据质量,从而提升信息的价值;其次是主数据对象对所有核心流程的适用性,从而通过优化的核心流程提高附加值。 307 | 308 | 主数据对象 — 主数据对象是正式的基本业务对象,在公司内的增值流程中使用。主数据对象描述结构(蓝图)和质量要求(如结构中的验证、允许值)。它们与用户交互,通常将参考数据(值列表)理解为公司的实际主数据。一个典型的例子是标准化的值列表,如 ISO 国家/地区代码和 ISO 货币代码。主数据使用这些列表作为分组、分层和分类的基础。在本文中,主数据不是唯一的参考列表,但都是正式的基本业务对象。 309 | 310 | ### 5.2 MDM 系统架构 311 | 作为业务转型,MDM 追求的目标是在公司范围内实施主数据管理。要在合理的运营成本下实现这个目标,IT 必须支持这个过程。一方面,这适用于 MDM 本身的手动支持流程,另一方面适用于数据处理和分发的自动化流程。 312 | 313 | 为此,有必要建立一个清晰的、包括系统相互依赖关系的系统架构。MDM 的系统架构描述目前的形势和计划的目标架构。以下结果对 MDM 发展规划非常有意义: 314 | 315 | 针对 MDM 发展规划的 IT 总体规划,以基础架构为重点 316 | ``` 317 | 包含数据模型和数据存储的主数据规划 318 | 跨公司信息流(价值和商品的流动)概述 319 | 运营流程(影响 MDM 发展规划和支持 MDM 所需的 IT 应用程序系统)的流程规划 320 | 设计领域包括包含必要的 MDM 特定系统的应用程序架构、对 IT 组件的支持、主数据物流的集成架构和基础系统架构。检查应用程序系统和候选 MDM 以确保它们提供相应的功能,同时用相应的标准对其进行评估。应用程序和集成组件基于与基础设施架构相互独立的基础架构平台。信息架构对 MDM 有着特殊意义。除了跨公司信息流(价值和商品的流动)以外,信息架构还描述了主数据对象、关联及其属性。 321 | ``` 322 | 323 | ## 六、ESB 324 | 325 | ### 6.1 定义 326 | ESB 是一个中间件解决方案,使用面向服务的模型来促进和支持异构环境之间的互操作性。没有规范准确定义了什么是 ESB 或者它应该提供什么功能。虽然 ESB 主要与“调节”和“集成”这类概念相关,但它还适合作为一个平台以类似于应用服务器的方式提供服务。ESB 代表被称作“集成”和“应用服务器”的产品类别的整合。 327 | 328 | 329 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4cadb75b85?w=312&h=51&f=jpeg&s=5612) 330 | 331 | 332 | ### 6.2 关键特性 333 | ESB 的一个关键特性是服务虚拟化。本文提出的 ESB 蓝图提供了各种功能的有序排列,构成了评估 ESB 产品的基础。 334 | 335 | ### 6.3 要点 336 | 企业服务总线应被视为一个架构样式或模式,而不是一款产品。 337 | ESB 没有定义或规范,因此也没有标准。 338 | ESB 可帮助实现系统间的松散耦合。 339 | ESB 上的服务是无状态的。长期运行的流程不属于 ESB,但是在使用 BPEL 和 BPMN 之类语言的 BPM 系统中受支持。 340 | “误用”ESB 来执行批处理时应小心谨慎,因为可能会对性能产生负面影响 341 | 342 | [更多详情](https://www.oracle.com/technetwork/cn/articles/soa/ind-soa-esb-1967705-zhs.html) 343 | 344 | 345 | 346 | --- 347 | ## 7. 关系说明 348 | 349 | ### 7.1. ESP && CSP && CEP 350 | 351 | ESP 与 CSP 之间的区别到底是什么?ESP 是流的处理,其中事件流是按时间顺序排列的事件序列,如股票行情自动收录器。而 CEP 工作在称为“事件云”的“云”上。事件云是来自 IT 系统不同部分的多个事件生成活动的结果。事件云可能包含多个流。因此,流是云的一个特殊实例。 352 | 353 | 在流内使用时间顺序有自己的优点:处理速度快,因为只有少数几个事件需要保存在缓冲区中。但是,依赖关系在云中非常重要:发生了哪些依赖事件?或者通常更精彩的是:或许没有发生哪些事件? 354 | 355 | 很明显,事件流处理侧重于高速处理,而 CEP 的重点是从事件云提取信息。在实践中,由于 ESP 和 CEP 之间的差别变得模糊,所以更强大的 CEP 占据了主导地位。 356 | 357 | 358 | ### 7.2. SOA && EDA 359 | 360 | SOA 标识符是服务的松散耦合、客户端在提供者与使用者之间发起的 1:1 通信以及同步响应行为。EDA 的标识符是分离的交互、n:m 通信、事件驱动的操作和异步操作。我们认为没有必要确定一端或另一端。SOA 为 EDA 提供了非常坚实的基础,应用程序可以同时采用这两种风格。在以下情况下,组件应使用 SOA 调用服务: 361 | 362 | ``` 363 | 确切知道要调用哪个服务 364 | 服务将只调用一次 365 | 期待得到关于服务完成的应答 366 | 期待应答 367 | 在以下情况下,组件应使用 EDA 发布事件: 368 | ``` 369 | ``` 370 | 在某些情况下,通知所有相关接收方 371 | 不知道事件的相关接收方 372 | 不知道接收方如何对该事件做出反应 373 | 不同接收方对同一事件有不同反应 374 | 涉及从发送方到接收方的单向通信 375 | ``` 376 | 377 | 从这方面来说,“2 + 2 > 4”,因为这两种架构风格的组合大于各部分之和。SOA 在执行`预定义的流程和逻辑`时使用`“请求-应答”`通信模式(可能是`异步方式`,请求与响应之间的时间间隔比较长)。相比之下,ED 应用程序使用典型的`“发布者/订阅者”`模式,在某些情况下可处理`大量事件`,旨在创建更少的新“可操作”事件。SOA 与 EDA 是相辅相成的:结合使用可以创建按需提供的高商业价值应用程序 378 | 379 | #### 7.2.1 多事件航班 380 | 经常乘飞机旅行的人都非常熟悉一个令人不快的问题“我的行李在哪里?”在值机柜台,旅客与行李分离。飞行结束时,旅客需要经过一系列流程才能取回行李,包括: 381 | 382 | ``` 383 | 办票柜台 384 | 安检 385 | 行李处理 386 | 舱门操作 387 | 航班操作 388 | 机场运作控制 (BAM) 仪表盘 389 | 客户服务 390 | ``` 391 | 最好的临时结果是飞机按时起飞,乘客和行李都在飞机上。然而,我们很多人都知道,可能会发生许多导致事情变得复杂的事件。行李可能在会在办理登记手续与登机之间丢失。乘客可能因安检处排队导致误机。行李可能包含禁带物品,需要搜查。航班可能取消,乘客可能改飞其他地方。乘客办理登记手续后可能决定改签航班。也可能发生其他复杂情况。 392 | 393 | 在这种情况下,SOA、EDA 或两者的组合 394 | 395 | 在做决定之前,需要考虑的是:所描述的场景并不是单个“登机服务”或流程。而是一系列相互影响的服务/流程。交互非常复杂,取决于多个边界条件,因此这是一个典型的“感知与响应”场景,或者说是在必要时启动 SOA 服务的 EDA 技术。试图将这种场景统一在一个可执行的流程中势必会陷入一片混乱。 396 | 397 | ``` 398 | 1. 办票:乘客办理登记手续、检查行李 399 | 2. 安检:乘客进入/离开安检区 400 | 3. 行李处理:在安检站扫描行李、行李装入集装箱 401 | 4. 舱门操作:舱门打开、登机、最后登机、关闭 402 | 5. 航班操作:登机口、装载集装箱、出发、起飞 403 | 6. 客户服务:新航班复查行李 404 | ``` 405 | 406 | 407 | ### 7.3. SOA 和 MDM 408 | 409 | SOA 的一个重要优点是 IT 组件的`松散耦合`。这有利于`组件重用`,并且组件可以`更轻松`、`更灵活`地`支持新功能或新流程` 。 410 | 411 | MDM 应基于`面向服务的概念`,并提供`通用组件(或服务)以实现数据维护和主数据检索的一致性`。在这里,SOA 架构理念再次与 MDM 不谋而合。这一论断支持了两个不同的观点: 412 | ``` 413 | MDM 业务服务 — 用于维护和验证主数据的可重用业务逻辑 414 | MDM 信息服务 — 业务流程中使用的可重用信息 415 | ``` 416 | 417 | 418 | ### 7.4. ESB && EDA && SOA 419 | 420 | ###### ESB连接EDA和SOA 421 | 422 | 企业服务总线(Enterprise Service Bus,ESB)在异类平台和环境间建立联系,充当允许不同应用程序进程之间进行通信的中间层。部署到企业服务总线的服务可以由使用者或事件触发。它同时支持同步方式和异步方式,可促进一个或多个参与者之间的交互。因此 ESB 可提供 SOA 和 EDA 范例的所有功能。“ESB提供了消息的传输,格式的转换等关键功能,为服务的请求者和服务提供者之间架设了沟通的桥梁,是企业应用基础架构的粘合剂。” 甲骨文公司大中华区高级技术经理黄建勇说。 423 | 424 | 企业服务总线可连接各个异类节点并作为中介传递其间的所有通信和交互,这些节点可分散在面向服务的体系结构(同步一对一方法)和事件驱动的体系结构(异步多对多方法)中。ESB 是目前处理集成挑战的最有效方法,是可提供最大业务灵活性和不同应用程序间的高效连接技术解决方案。 425 | 426 | EDA应用在很多ESB(企业服务总线)产品中,比如FiornaoESB中间件产品支持同步、异步和请求响应事件,事件处理和传输实用不同的技术例如JMS,HTTP,电子邮件和基于XML的RPC等。比如“政府网上监察系统”通过对被监察对象(系统)数据的实时采集,通过EDA技术的事件触发,事件过滤,实现对违规、违法、越权行政、超时限行政等问题进行通知和督办等。 427 | 428 | ### 7.5.iBPM && BPM && CEP 429 | 430 | 431 | BPM是以规范标准的方式对业务流程进行建模以及执行的一组工具,而iBPM 是BPM的智能提升。从流程发现、设计、建模、 执行、监控以及分析优化的流程全生命周期的各个阶段,融合了人工智能、复杂事件处理、云服务和移动技术。 432 | 433 | 把事件技术跟操作联系在一起,让分析结果跟应用集成及有用的商业活动关联,这些对于业务流程管理(BPM)的实践者来说是重要的。 434 | 435 | ## 8.Serverless 436 | 437 | Serverless(无服务器架构)指的是由开发者实现的服务端逻辑运行在无状态的计算容器中,它由事件触发, 完全被第三方管理,其业务层面的状态则被开发者使用的数据库和存储资源所记录。 438 | 439 | 440 | ![image](https://user-gold-cdn.xitu.io/2018/12/8/1678d2a2986ef8d6?w=694&h=502&f=jpeg&s=24801) 441 | 442 | 443 | ### 8.1 Serverless架构的优点 444 | 445 | - 降低运营成本: 446 | 447 | Serverless是非常简单的外包解决方案。它可以让您委托服务提供商管理服务器、数据库和应用程序甚至逻辑,否则您就不得不自己来维护。由于这个服务使用者的数量会非常庞大,于是就会产生规模经济效应。在降低成本上包含了两个方面,即基础设施的成本和人员(运营/开发)的成本。 448 | 449 | - 降低开发成本: 450 | 451 | IaaS和PaaS存在的前提是,服务器和操作系统管理可以商品化。Serverless作为另一种服务的结果是整个应用程序组件被商品化。 452 | 453 | 454 | - 扩展能力: 455 | 456 | Serverless架构一个显而易见的优点即“横向扩展是完全自动的、有弹性的、且由服务提供者所管理”。从基本的基础设施方面受益最大的好处是,您只需支付您所需要的计算能力。 457 | 458 | - 更简单的管理: 459 | 460 | Serverless架构明显比其他架构更简单。更少的组件,就意味着您的管理开销会更少。 461 | 462 | - “绿色”的计算: 463 | 464 | 按照《福布斯》杂志的统计,在商业和企业数据中心的典型服务器仅提供5%~15%的平均最大处理能力的输出。这无疑是一种资源的巨大浪费。随着Serverless架构的出现,让服务提供商提供我们的计算能力最大限度满足实时需求。这将使我们更有效地利用计算资源。 465 | 466 | ## 9. FAAS 467 | 468 | FaaS(Functions as a Service)函数即服务,FaaS是无服务器计算的额一种形式,当前使用最广泛的是AWS的Lambada。 469 | 470 | 现在当大家讨论Serverless的时候首先想到的就是FaaS,有点甚嚣尘上了。FaaS本质上是一种事件驱动的由消息触发的服务,FaaS供应商一般会集成各种同步和异步的事件源,通过订阅这些事件源,可以突发或者定期的触发函数运行。 471 | 472 | ![image](https://user-gold-cdn.xitu.io/2018/12/8/1678d2ae554f5665?w=834&h=420&f=jpeg&s=33822) 473 | 474 | 475 | 传统的服务器端软件不同是经应用程序部署到拥有操作系统的虚拟机或者容器中,一般需要长时间驻留在操作系统中运行,而FaaS是直接将程序部署上到平台上即可,当有事件到来时触发执行,执行完了就可以卸载掉。 476 | 477 | 478 | 479 | 480 | ![image](https://user-gold-cdn.xitu.io/2018/12/8/1678d2ae5a09d990?w=294&h=420&f=jpeg&s=21295) 481 | 482 | 483 | 484 | ![image](https://user-gold-cdn.xitu.io/2018/12/8/1678d2ae6753e1fe?w=2500&h=1820&f=png&s=115235) 485 | 486 | 487 | ### 9.1 Serverless && FaaS 488 | 489 | Function 可以理解为一个代码功能块,这个功能块具体包含多少功能,无法明确给出定义,但有一个明确的指标:冷启动时间需要在毫秒数量级。因为 FaaS 的本质上是以程序的快速启动来实现正真的按需运行,按需伸缩,以及高可用。Function 配合调度系统,就可以完全做到开发者对服务运行的实例无感,真 Serverless。 490 | 491 | 492 | Serverless 比 FaaS 的外延要广,FaaS 主要解决的是用户自定义的代码逻辑如何做到 Serverless,可以叫做 Serverless Compute,同时它也是事件驱动架构的一种,从一张图可以看出二者区别。 493 | 494 | 495 | 496 | ![image](https://user-gold-cdn.xitu.io/2018/12/8/1678d2c431ce03c1?w=1734&h=1088&f=png&s=410198) 497 | 498 | ### 9.2 从云的发展来看 FaaS 499 | 500 | 第一阶段的云主要解决硬件资源(网络,计算,存储)的运维和供给问题,也就是 IaaS 云,可以理解成基于硬件资源的共享经济。IaaS 云的交付的主要是资源,接口以及控制台也是面向资源的,尽量以模拟物理机房环境来降低应用的迁移成本。而云发展到当前阶段来看,出现了两种需求: 501 | 502 | ###### 正真的按需计算 503 | >原来云的按需计算只是虚拟机维度的,按时间计费以及弹性伸缩,并不能正真做到按需计算,计算和内存资源都是预申请规划的,和服务的请求并发数并没有明确的关系,哪怕一段时间一个请求没有,资源还是依然占用。而 FaaS 可以做到按请求计费,不需要为等待付费,可以做到更高效的资源利用率。 504 | 505 | ###### 面向应用 506 | 507 | > 本质上用户对云的期望是应用的运行环境,并且最好是只让用户关心业务逻辑,而不需要关心,或者尽量少关心技术逻辑(比如监控,性能,弹性,高可用,日志追踪等)。这也是云原生应用(Cloud Native Application)这个概念提出的背景。 508 | 509 | 510 | ##### 云原生应用就是让渡一部分功能给云,以实现弹性,高可用,故障恢复,降低研发运维成本的应用 511 | 512 | 513 | 但 FaaS 给出来一个方案。就是应用只需要把包含自己业务逻辑的 Function 提交给云,其他的事情由云来完成。这样,云相当于直接接管了业务逻辑模块,然后其他的技术功能直接由云来提供,不依赖开发者在自己应用中引入标准化框架来实现。 514 | 515 | 516 | 517 | --- 518 | ###### 附录: 519 | ###### CEP 520 | 521 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4cb7273583?w=572&h=226&f=gif&s=14297) 522 | 523 | 524 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4cb48d44ba?w=411&h=265&f=gif&s=9581) 525 | 526 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4cbf6f44e0?w=572&h=421&f=gif&s=25349) 527 | 528 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4cb7fb1cac?w=414&h=240&f=gif&s=16042) 529 | 530 | ![image](https://user-gold-cdn.xitu.io/2018/12/3/16773f4d77b6ad80?w=1144&h=682&f=svg&s=719124) 531 | 532 | 533 | --- 534 | ###### 仓库: 535 | 536 | --- 537 | ###### 参考: 538 | - [FRP定义](http://conal.net/papers/icfp97/) 539 | - [事件驱动架构](https://baike.baidu.com/item/%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8%E6%9E%B6%E6%9E%84/883637) 540 | - [响应式宣言](https://linux.cn/article-8773-1.html) 541 | - [The Reactive Manifesto](https://www.reactivemanifesto.org/glossary#Message-Driven) 542 | 543 | - [EDA&&SOA](http://tech.it168.com/a2009/0313/268/000000268470.shtml) 544 | - [CEP](http://www.cnblogs.com/holbrook/archive/2012/11/06/2756759.html) 545 | - [Google_cloud_platform_CEP](https://cloud.google.com/solutions/architecture/complex-event-processing) 546 | - [iBPM](https://kknews.cc/tech/blyyqbm.html) 547 | - [oracle](https://www.oracle.com/technetwork/cn/articles/soa/ind-soa-toc-1934143-zhs.html) 548 | - [bpmjournal](https://www.ibm.com/developerworks/cn/websphere/bpmjournal/0812_boughannam/0812_boughannam.html) 549 | 550 | --- 551 | ###### Company 552 | - [tibco](https://wiki.mbalib.com/wiki/TIBCO%E8%BD%AF%E4%BB%B6%E5%85%AC%E5%8F%B8) 553 | - Gartner 554 | 555 | 556 | --- 557 | ###### DISS 558 | - [eda-versus-cep-and-soa](https://soa-eda.blogspot.com/2008/10/eda-versus-cep-and-soa.html) 559 | - [cep-eda-and-soa](https://apama.typepad.com/my_weblog/2008/10/cep-eda-and-soa.html) 560 | --------------------------------------------------------------------------------