首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

消息队列入门(三)JMS标准及实现

消息中间件 消息中间件即Message-oriented middleware(MOM),消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。 通过提供消息传递和消息排队模型,消息中间件可以在分布式环境下扩展进程间的通信。 消息中间件可以即支持同步方式,又支持异步方式。 异步中间件比同步中间件具有更强的容错性,在系统故障时可以保证消息的正常传输。异步中间件技术又分为两类:广播方式和发布/订阅方式。 消息中间件应用主要有两个优点:异步和解耦。 JMS规范标准 JMS即Java消息服务(Java Message Service),JMS是一个基于Java平台面向消息中间件(MOM)的API,用于在两个应用程序之间, 或分布式系统中发送消息,进行异步通信。 Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。 JMS是类似于JDBC(Java Database Connectivity),并不局限于某个具体消息中间件, JDBC 是可以用来访问许多不同关系数据库的 API, 而 JMS 则提供同样与中间件无关的访问方法,以访问消息收发服务。 >>JMS对象模型 ConnectionFactory: 连接工厂,JMS 用它创建连接Connection,一般设为单例模式, 一旦创建,就一直运行在应用容器内,客户端使用JNDI查找连接工厂,然后利用连接工厂创建一个JMS连接。 Connection: JMS连接表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。 Session: JMS会话表示JMS客户与JMS服务器之间的会话状态。JMS会话建立在JMS连接上,表示客户与服务器之间的一个会话线程。 Destination: 消息的目的,包括队列(PTP),主题(Pub/Sub)。 Message Producer和Message Consumer: 生产者和消费者对象由Session对象创建,用于发送和接收消息。 Message: JMS 消息由以下几部分组成:消息头,属性,消息体。 消息头(header):JMS消息头包含了许多字段,它们是消息发送后由JMS提供者或消息发送者产生,用来表示消息、设置优先权和失效时间等等,并且为消息确定路由Routing。 属性(property):由消息发送者产生,用来添加删除消息头以外的附加信息。 消息体(body):由消息发送者产生,JMS中定义了5种消息体:ByteMessage、MapMessage、ObjectMessage、StreamMessage和TextMessage。 两种消息传递模型 (1)点对点模型(Point-to-Point) 点对点模型用于消息生产者和消息消费者之间点到点的通信。消息生产者将消息发动到由某个名字标识的特定消费者。这个名字实际上对应于消息服务中的一个队列(Queue),在消息传动给消费者之前它被存储在这个队列中。队列可以是持久的,以保证在消息服务出现故障时仍然能够传递消息。 (2)发布-订阅模型(Publish/Subscribe) 发布-订阅模型用称为主题(topic)的内容分层结构代替了PTP模型中的惟一目的地, 发送应用程序发布自己的消息,指出消息描述的是有关分层结构中的一个主题的信息。希望接收这些消息的应用程序订阅了这个主题。订阅包含子主题的分层结构中的主题的订阅者可以接收该主题和其子主题发表的所有消息 本文转自邴越博客园博客,原文链接:http://www.cnblogs.com/binyue/p/4738360.html,如需转载请自行联系原作者

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

Linux从入门到精通系列之基础篇

首先我们先来说一下什么是Linux? 我们一般都听说过Windows,而一提到linux大部分人都很陌生,毕竟台式机、笔记本都是Windows操作系统。首先我们要知道 Linux 这玩意儿跟Windows是一样的都是在计算机上面运行的操作系统,所以说 Linux 就是一个操作系统。问题是Linux 可以在哪些种类的计算机上面运行呢?而 Linux 源自哪里?为什么Linux是免费的呢?这些我们都得来谈一谈先! 由上图中我们可以看到其实核心与硬件的关系非常的强烈。早期的 Linux 是针对 386 来开发的,由于Linux 只是一套操作系统并不含有其他癿应用程序,因此很多工程师在下载了 Linux 核心并且实际安装之后,就只能看着计算机开始运行了! 接下来这些高级工程师为了自己的需求,再在 Linux 上面安装他们所需要的软件就是了。 由与不同的硬件他的功能函数并不相同,例如 IBM 的Power CPU 与Intel 的 x86 架构就是不一样! 所以同一套操作系统是无法在不同的硬件平台上面运行的!举例来说,如果你想要让 x86 上面跑的那套操作系统也能够在 Power CPU 上运行时,就得要将该操作系统进行修改才行。如果能够参考硬件的功能函数并据以修改你癿操作系统程序代码,那经过改版后的操作系统就能够在另一个硬件平台上面运行了。这个动作我们通常就称为『软件移植』了! Linux 提供了一个完整的操作系统当中最底层的硬件控制与资源管理的完整架构,这个架构是沿袭Unix 良好的传统来的,所以相当的稳定而功能强大! ●1991 年:芬兰大学生 Linus Torvalds 的一则简讯到了 1991 年,芬兰的赫尔辛基大学的Linus Torvalds 在 BBS 上面贴了一则消息,宣称他以 bash, gcc 等工具写了一个小小的核心程序,这个核心程序可以在 Intel 的 386 机器上面运行,让很多人很感兴趣!仍此开始了 Linux 不平凡的路程! 一共经历了三个阶段:1.单人维护阶段 2.广大黑客志工加入阶段 3.核心功能细部分工发展阶段 ●Linux的核心版本 Linux 的核心版本编号有点类似如下的样子: 如前所述,因为对与 Linux 核心的开发者太多了,以致于造成 Linux 核心经常性的变动。 但对于一般家庭计算机或企业关键应用的话,常变动的核心并不适合的。因此托瓦兹便将核心的发展趋势分为两股, 并根据这两股核心的发展分别给予不同的核心编号,那就是: 好了,经过上面的说明,我们知道了 Linux 其实就是一个操作系统最底层的核心及其提供的核心工具。他是 GNU GPL 授权模式,所以,任何人均可取得原始码与可执行这个核心程序,并且可以修改。 此外,因为 Linux 参考 POSIX 设计规范,于是兼容于 Unix 操作系统,故亦可称之为 Unix Like 的一种。 ●GNU(GNU isNotUnix) 1984年由Richard Stallman发起并创建,官方网站:http://www.gnu.org ●GPL(GNU General Public License) 1.GNU自由软件的通用许可协议 2.允许用户任意复制、传递、修改及再发布 3. 基于自由软件修改再次发布的软件,仍需遵守GPL 底下列出几个主要的Linux发行者网址: Red Hat: http://www.redhat.com Fedora: http://fedoraproject.org/ Mandriva: http://www.mandriva.com Novell SuSE: http://www.novell.com/linux/ Debian: http://www.debian.org/ Slackware: http://www.slackware.com/ Gentoo: http://www.gentoo.org/ Ubuntu: http://www.ubuntu.com/ CentOS: htpp://www.centos.org/ ●Linux的特色 那么这个系统有什么特别的功能呢?简单的说: 1. 自由与开放的使用与学习环境 2. 配备需求廉价 3. 核心功能强大而稳定 4. 独立作业 目前Linux已经是想当成熟的一套操作系统咯,而且不耗资源又可以自由获取,呵呵,可以说造成微软相当大的压力呀!这也是造成Linux成为最近几年来最受瞩目的操作系统之一,如前所述,他会受到的瞩目原因是因为他是Free的,就是可以自由获取的操作系统啦!然后他是开放性的系统,也就是说你可以随时的取得程序的源代码,这对于程序开发工程师是很重要的。而且他虽然是Free的自由软件,但是功能很强大!另外,Linux对于硬件需求不是很高,这一点更造成他流行的原因。 反正Linux好处说不完啦,不过虽然Linux具有这样多的好处,但是他有一个致命的地方,使他普及率受到很大的限制,就是Linux需要使用相关的命令字符来进行系统管理,虽然近年来有很多的图形接口开发使用在Linux上面,但毕竟要熟悉Linux还是以命令字符比较好,因此要接受Linux的玩家必须会使用相关的命令字符,而不是用鼠标点一点就行的。 下面介绍几款开源软件: Firefox(火狐)浏览器OpenOffice办公软件Apache网站服务器软件 好了,天儿也不早了今天就先讲到这里我会在今后的日子里继续为大家讲解Linux的相关知识。 本文转自Devin 51CTO博客,原文链接:http://blog.51cto.com/devingeng/1330937

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

OpenStack入门修炼之网络虚拟化基础(20)

1.Linux Bridge的基本概念 假设宿主机有 1 块与外网连接的物理网卡 eth0,上面跑了 1 个虚机 VM1,现在有个问题是: 如何让 VM1 能够访问外网? ① 给 VM1 分配一个虚拟网卡 vnet0,通过 Linux Bridge br0 将 eth0 和 vnet0 连接起来,如下图所示 Linux Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备,其功能大家可以简单的理解为是一个二层交换机或者 Hub。多个网络设备可以连接到同一个 Linux Bridge,当某个设备收到数据包时,Linux Bridge 会将数据转发给其他设备。 在上面这个例子中,当有数据到达 eth0 时,br0 会将数据转发给 vnet0,这样 VM1 就能接收到来自外网的数据; 反过来,VM1 发送数据给 vnet0,br0 也会将数据转发到 eth0,从而实现了 VM1 与外网的通信。 现在我们增加一个虚机 VM2,如下图所示 VM2 的虚拟网卡 vnet1 也连接到了 br0 上。 现在 VM1 和 VM2 之间可以通信,同时 VM1 和 VM2 也都可以与外网通信。 2.理解virbr0 virbr0 是 KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供 NAT 访问外网的功能。 virbr0 默认分配了一个IP 192.168.122.1,并为连接其上的其他虚拟网卡提供 DHCP 服务。 [root@linux-node1 ~]# ifconfig brqc39c1348-5a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.56.11 netmask 255.255.255.0 broadcast 192.168.56.255 ether 00:0c:29:4c:ef:31 txqueuelen 0 (Ethernet) RX packets 1069698 bytes 374890434 (357.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 854554 bytes 289390857 (275.9 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::20c:29ff:fe4c:ef31 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:4c:ef:31 txqueuelen 1000 (Ethernet) RX packets 1272820 bytes 454742027 (433.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 948074 bytes 428034564 (408.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 12361940 bytes 4186785589 (3.8 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 12361940 bytes 4186785589 (3.8 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 tapae04cfac-d0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 6a:ef:28:f7:c5:90 txqueuelen 1000 (Ethernet) RX packets 5 bytes 438 (438.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 13043 bytes 2231018 (2.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:8b:7a:13 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 查看虚拟机 [root@linux-node1 ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- - centos 关闭 查看虚拟机网卡信息 [root@linux-node1 ~]# virsh domiflist centos 接口 类型 源 型号 MAC ------------------------------------------------------- - network default virtio 52:54:00:e4:75:83 查看桥接网卡信息,可以看到virbr0-nic桥接到virbr0网卡上 [root@linux-node1 ~]# brctl show bridge name bridge id STP enabled interfaces brqc39c1348-5a 8000.000c294cef31 no eth0 tapae04cfac-d0 virbr0 8000.5254008b7a13 yes virbr0-nic 启动虚拟机 [root@linux-node1 ~]# virsh start centos 域 centos 已开始 [root@linux-node1 ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- 1 centos running 使用TightVNC连接192.168.56.11,查看网卡信息 [root@linux-node1 ~]# ssh 192.168.122.169 root@192.168.122.169's password: Last login: Tue Dec 12 15:04:59 2017 ping外网可通 [root@localhost ~]# ping www.baidu.com PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data. 64 bytes from 14.215.177.39: icmp_seq=1 ttl=127 time=13.4 ms 64 bytes from 14.215.177.39: icmp_seq=2 ttl=127 time=9.14 ms 64 bytes from 14.215.177.39: icmp_seq=3 ttl=127 time=8.47 ms 64 bytes from 14.215.177.39: icmp_seq=4 ttl=127 time=15.5 ms 64 bytes from 14.215.177.39: icmp_seq=5 ttl=127 time=8.85 ms 64 bytes from 14.215.177.39: icmp_seq=6 ttl=127 time=8.85 ms ^C --- www.a.shifen.com ping statistics --- 6 packets transmitted, 6 received, 0% packet loss, time 5012ms rtt min/avg/max/mdev = 8.473/10.716/15.538/2.741 ms 没有问题,可以访问外网,说明 NAT 起作用了。 需要说明的是,使用 NAT 的虚拟机 centos可以访问外网,但外网无法直接访问 centos。 因为 centos 发出的网络包源地址并不是 192.168.122.169,而是被 NAT 替换为宿主机的 IP 地址了。 这个与使用 br0 不一样,在 br0 的情况下,centos 通过自己的 IP 直接与外网通信,不会经过 NAT 地址转换。 版权声明:原创作品,谢绝转载。否则将追究法律责任 本文转自 IT_外卖小哥 51CTO博客,原文链接:http://blog.51cto.com/jinlong/2049817

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

spark入门知识和job任务提交流程

spark是Apache开源社区的一个分布式计算引擎,基于内存计算,所以速度要快于hadoop. 下载 地址spark.apache.org 安装 复制一台单独的虚拟机,名c 修改其ip,192.168.56.200 修改其hostname为c,hostnamectl set-hostname c 修改/etc/hosts加入对本机的解析 重启网络服务 systemctl restart network 上传spark安装文件到root目录 解压spark到/usr/local下,将其名字修改为spark 本地运行模式 使用spark-submit提交job cd /usr/local/spark ./bin/spark-submit --class org.apache.spark.examples.SparkPi ./examples/jars/spark-examples_2.11-2.1.0.jar 10000 使用spark-shell进行交互式提交 创建root下的文本文件hello.txt ./bin/spark-shell 再次连接一个terminal,用jps观察进程,会看到spark-submit进程 sc sc.textFile("/root/hello.txt") val lineRDD = sc.textFile("/root/hello.txt") lineRDD.foreach(println) 观察网页端情况 val wordRDD = lineRDD.flatMap(line => line.split(" ")) wordRDD.collect val wordCountRDD = wordRDD.map(word => (word,1)) wordCountRDD.collect val resultRDD = wordCountRDD.reduceByKey((x,y)=>x+y) resultRDD.collect val orderedRDD = resultRDD.sortByKey(false) orderedRDD.collect orderedRDD.saveAsTextFile("/root/result") 观察结果 简便写法:sc.textFile("/root/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().collect 使用local模式访问hdfs数据 start-dfs.sh spark-shell执行:sc.textFile("hdfs://192.168.56.100:9000/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().collect (可以把ip换成master,修改/etc/hosts) sc.textFile("hdfs://192.168.56.100:9000/hello.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortByKey().saveAsTextFile("hdfs://192.168.56.100:9000/output1") spark standalone模式 在master和所有slave上解压spark 修改master上conf/slaves文件,加入slave 修改conf/spark-env.sh,export SPARK_MASTER_HOST=master 复制spark-env.sh到每一台slave cd /usr/local/spark ./sbin/start-all.sh 在c上执行:./bin/spark-shell --master spark://192.168.56.100:7077 (也可以使用配置文件) 观察http://master:8080 spark on yarn模式 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1968175

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

SQLite 入门教程(二)创建、修改、删除表

一、数据库定义语言 DDL 在关系型数据库中,数据库中的表 Table、视图 View、索引 Index、关系 Relationship 和触发器 Trigger 等等,构成了数据库的架构 Schema。 在 SQL 语句中,专门有一些语句用来定义数据库架构,这些语句被称为“数据库定义语言”,即 DDL。 SQLite 数据库引擎支持下列三种 DDL 语句: CREATE ALTER TABLE DROP 其中,CREATE 语句用来创建表 Table、视图 View、索引 Index、关系 Relationship 和触发器 Trigger, DROP语句用来删除表 Table、视图 View、索引 Index、关系 Relationship 和触发器 Trigger, ALTER TABLE 语句用来改变表的结构。 今天这一篇只涉及到表的相关内容,视图、触发器等到后面再讲。 二、SQLite 中的数据类型 SQLite 数据库中的数据一般由以下几种常用的数据类型组成: NULL - 空值 INTEGER - 有符号整数 REAL - 浮点数 TEXT - 文本字符串 BLOB - 二进制数据,如图片、声音等等 SQLite 也可以接受其他数据类型。 三、创建表 CREATE TABLE 首先,创建一个 test.db 数据库并进入 SQLite 命令行环境,还记得怎么做吗? myqiao@ubuntu:~$ sqlite3 test.db -- Loading resources from /home/myqiao/.sqliterc SQLite version 3.7.4 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables sqlite> 向上面这样,我们就在终端中创建了一个 test.db 数据库, 并且通过 .tables 命令查询数据库中的表,结果没有任何返回, 因为数据库本来就是空的嘛。 下面我们创建一个 Student 表,其中包含 Id、Name、Age 等字段. sqlite> sqlite> CREATE TABLE Students(Id integer,Name text,age integer); sqlite> .tables Students sqlite> .schema Students CREATE TABLE Students(Id integer,Name text,age integer); sqlite> 向上面这样,一个 Students 表就被建立了,这回再运行 .tables 命令就有响应了, 系统告诉我们数据库中现在有一个 Students 表, 运行 .schema 命令,返回了我们创建这个表的 SQL 命令。 四、修改表 ALTER TABLE SQLite 仅仅支持 ALTER TABLE 语句的一部分功能, 我们可以用 ALTER TABLE 语句来更改一个表的名字,也可向表中增加一个字段(列), 但是我们不能删除一个已经存在的字段,或者更改一个已经存在的字段的名称、数据类型、限定符等等。 改变表名 - ALTER TABLE 旧表名 RENAME TO 新表名 增加一列 - ALTER TABLE 表名 ADD COLUMN 列名 数据类型 限定符 下面我们来演示一下,将前面的 Students 表的名字改为 Teachers sqlite> sqlite> .tables Students sqlite> ALTER TABLE Students RENAME TO Teachers; sqlite> .tables Teachers sqlite> 原来数据库中只有一个 Students 表,改名以后再运行 .tables 命令,发现 Students 表已经没了,现在变成了 Teachers 表。 下面改变 Teachers 表的结构,增加一个 Sex 列 sqlite> sqlite> .schema Teachers CREATE TABLE "Teachers"(Id integer,Name text,age integer); sqlite> ALTER TABLE Teachers ADD COLUMN Sex text; sqlite> .schema Teachers CREATE TABLE "Teachers"(Id integer,Name text,age integer, Sex text); sqlite> 五、删除表 DROP TABLE 删除一个表很简单,只要给出表名即可 删除表 - DROP TABLE 表名 下面,我们将 test.db 中的 Teachers 表删除 sqlite> sqlite> .tables Teachers sqlite> DROP TABLE Teachers; sqlite> .tables sqlite> 删除 Teachers 表后再运行 .tables 命令,发现数据库已经空了。 六、后续内容 其实创建一个表远没有这么简单,表的每一列可以有很多限定符,比如主列、非空、限制、默认值、唯一、键等等,这些内容留到下一篇吧 //=================================================================================================== 本文转自左洸博客园博客,原文链接:http://www.cnblogs.com/myqiao/archive/2011/07/12/2103527.html,如需转载请自行联系原作者

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

领域模型驱动设计(Domain Driven Design)入门概述

软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 } 分层架构 } 实体 } 值对象 } 服务 } 模块 } 聚合 } 工厂 } 资源库 分层架构: } 将领域模型相关的代码集中到一个层中,把它从用户界面、应用和基础设施代码中分隔开来 } 释放领域对象的显示自己、保存自己、管理应用任务等职责,让它专注于展现领域模型 } 复杂的程序切分成层 } 层中采用内聚的设计 } 层仅依赖于它底下的那层 实体entity: 有一类对象拥有唯一标识符 } 能够跨越系统的生命周期甚至能超越软件系统的一系列的延续性和标识符 } 这样的对象称为实体。 值对象-value Object } 对某个对象是什么不感兴趣,只关心它拥有的属性 } 用来描述领域的特殊方面、且没有标识符的一个对象,叫做值对象 } 能被简单的创建和丢弃,生命周期中不会被持久化 } 值对象可以被共享,值对象应该不可变 服务-service(比webservice更细粒度服务描述) } 领域中的一些动词,代表了领域中的一个重要的行为,却不属于任何对象 ◦服务执行的操作涉及一个领域概念,这个领域概念通常不属于一个实体或者值对象 ◦被执行的操作涉及到领域中的其他的对象 ◦操作是无状态的 } 服务对象不再拥有内置的状态 } 服务对象担当重要的协调功能 } 开发通用语言时,领域中的主要概念被引入到语言中,语言中的名词很容易被映射成对象。 语言中对应那些名词的动词变成那些对象的行为。但是有些领域中的动作,它们是一些动词,看上去却不属于任何对象。它们代表了领域中的一个重要的行为,所以不能忽略它们或者简单的把它们合并到某个实体或者值对象中。给一个对象增加这样的行为会破坏这个对象,让它看上去拥有了本该属于它的功能。 模块 } 将相关领域模型提炼分类,分而治之 } 将高关联度的模型分组到一个模块以提供尽可能大的内聚(以能完整完成任务为准) } 分层是水平划分 } 模块是垂直划分(Domain内部) 参考架构概述 } 领域驱动设计(DomainDriven Design)有一个官方的sample工程,名为DDDSample } 官网:http://dddsample.sourceforge.net/ } 该工程给出了一种实践领域驱动设计的参考架构 架构概述 详细架构 架构详解:Interfaces-接口层 } 该层包含与其他系统进行交互的接口与通信设施,在多数应用里 } 可能提供包括WebServices、RMI或Rest等在内的一种或多种通信接口 } 该层主要由Facade、DTO和Assembler三类组件构成,三类组件均是典型的J2EE模式 DTO } DTO- DataTransfer Object(数据传输对象),也常被称作VO-ValueObject(值对象) } DTO设计之初是为了将细粒度的领域对象包装为粗粒度的数据结构,减少网络通信并简化调用接口 DTO 作用 } 减少网络流量 } 简化远程对象和远程接口 } 传输更多的数据减少远程调用次数 } 避免将领域状态跨层次传递 } 由于同步和版本控制增加了复杂性 DTO 应用时序图 Assembler } DTO与领域对象之间的相互转换工作多由Assembler承担 } 因此Assembler几乎总是同DTO一起出现。 Assembler 实现方案 Façade } 实践Facade的过程中最难把握的问题就是Facade的粒度问题。 } 传统的Service均以实体为单位进行组织,而Facade应该具有更粗粒度的组织依据,较为合适的粒度依据有: } 一个高度内聚的模块一个Facade } 或者是一个“聚合”(特指领域驱动设计)一个Facade. Facade 实现方案 Facade 应用时序图 Service } Service会与多种组件进行交互 } 这些组件包括: ◦其他的Service ◦领域对象 ◦Repository ◦DAO Service 应用时序图 Domain-领域层 } Domain层是整个系统的核心层,该层维护一个使用面向对象技术实现的领域模型,几乎全部的业务逻辑会在该层实现 } Domain层包含: ◦Entity(实体) ◦ValueObject(值对象) ◦Domain Event(领域事件) ◦Repository(仓储)等 Infrastructure-基础设施层 } 基础设施层nfrastructure为Interfaces、Application和Domain三层提供支撑 } 所有与具体平台、框架相关的实现会在Infrastructure中提供,避免三层特别是Domain层掺杂进这些实现,从而“污染”领域模型 } Infrastructure中最常见的一类设施是对象持久化的具体实现 “传统”架构-贫血领域模型 DDD && SOA } DDD 领域模型驱动设计 } SOA 面向服务的架构 http://blog.csdn.net/johnstrive/article/details/16805121 分类: 设计模式 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/5785269.html ,如需转载请自行联系原作者

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

简单实用的OkHttp3入门精简教程

自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 自定义View系列教程08–滑动冲突的产生及其处理 探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)— 核心基础 Android多分辨率适配框架(2)— 原理剖析 Android多分辨率适配框架(3)— 使用指南 本文将用最简的代码和语句介绍OkHttp3的常用基本操作。 准备工作 导入OkHttp3 compile 'com.squareup.okhttp3:okhttp:3.8.1' 添加权限 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 请注意:假若你看到此处不明白为什么需要做这些准备工作,那么请点击浏览器右上角的八叉 ( X ) Post,Get,上传,下载 package com.cn.okhttp01; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Environment; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * 原创作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ public class MainActivity extends AppCompatActivity { public final static String TAG="reborn"; private static final int REQUEST_CODE = 9527; private static String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init(){ mContext=this; verifyStoragePermissions(this); } private void testOkHttp(){ testUpload(); } public void verifyStoragePermissions(Activity activity) { int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, PERMISSIONS, REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { testOkHttp(); } else { Toast.makeText(mContext, "您未授权存储权限", Toast.LENGTH_LONG).show(); } break; default: } } //Get同步请求 public void testGet1(){ new Thread(new Runnable() { @Override public void run() { try{ String url="http://blog.csdn.net/lfdfhl"; OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); Response response=call.execute(); String result=response.body().string(); response.body().close(); Log.i(TAG,"测试Get同步请求 "+result); }catch (Exception e){ } } }).start(); } //Get异步请求 public void testGet2(){ new Thread(new Runnable() { @Override public void run() { try{ String url="http://blog.csdn.net/lfdfhl"; OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { int code=response.code(); String result=response.body().string(); response.body().close(); Log.i(TAG,"code="+code); Log.i(TAG,"测试Get异步请求 "+result); } }); }catch (Exception e){ } } }).start(); } //POST同步请求 public void testPost1(){ new Thread(new Runnable() { @Override public void run() { try{ String url="http://106.14.136.52:8080/user/login"; OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder requestBuilder=new Request.Builder(); FormBody.Builder formBodyBuilder=new FormBody.Builder(); formBodyBuilder.add("username","andy"); formBodyBuilder.add("password","123456"); RequestBody requestBody=formBodyBuilder.build(); requestBuilder.url(url); requestBuilder.post(requestBody); requestBuilder.addHeader("apikey","81bf9da930c7f9825a3c3383f1d8d766"); Request request=requestBuilder.build(); Response response=okHttpClient.newCall(request).execute(); int code=response.code(); String result=response.body().string(); response.body().close(); Log.i(TAG,"code="+code); Log.i(TAG,"测试Post同步请求 "+result); }catch (Exception e){ } } }).start(); } //POST异步请求 public void testPost2(){ new Thread(new Runnable() { @Override public void run() { try{ String url="http://106.14.136.52:8080/user/login"; OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder requestBuilder=new Request.Builder(); FormBody.Builder formBodyBuilder=new FormBody.Builder(); formBodyBuilder.add("username","andy"); formBodyBuilder.add("password","123456"); RequestBody requestBody=formBodyBuilder.build(); requestBuilder.url(url); requestBuilder.post(requestBody); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { int code=response.code(); String result=response.body().string(); response.body().close(); Log.i(TAG,"code="+code); Log.i(TAG,"测试Post异步请求 "+result); } }); }catch (Exception e){ } } }).start(); } //下载 public void testDownload(){ new Thread(new Runnable() { @Override public void run() { try{ String url="http://img.blog.csdn.net/20161023140032428"; final File downloadFile=new File(getExternalCacheDir().toString()+File.separator+"test.jpg"); OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if(response.isSuccessful()){ InputStream inputStream=response.body().byteStream(); FileOutputStream fileOutputStream=new FileOutputStream(downloadFile); int len=0; byte b []=new byte[1024*2]; while ((len=inputStream.read(b))!=-1){ fileOutputStream.write(b,0,len); } fileOutputStream.close(); inputStream.close(); } response.body().close(); Bitmap bitmap = BitmapFactory.decodeFile(downloadFile.getAbsolutePath()); Log.i(TAG,"width="+bitmap.getWidth()); Log.i(TAG,"height="+bitmap.getHeight()); } }); }catch (Exception e){ } } }).start(); } //上传 public void testUpload(){ new Thread(new Runnable() { @Override public void run() { try{ String url ="http:192.168.0.103:8081/SpringMVC07/testUpload/uploadFile.do"; OkHttpClient okHttpClient=new OkHttpClient(); MultipartBody.Builder multipartBodyBuilder=new MultipartBody.Builder(); //添加文件 File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"test.jpg"); String fileName=file.getName(); MediaType mediaType=MediaType.parse("image/*"); RequestBody requestBody=RequestBody.create(mediaType,file); multipartBodyBuilder.setType(MultipartBody.FORM); multipartBodyBuilder.addFormDataPart("photo",fileName,requestBody); //添加参数 multipartBodyBuilder.addFormDataPart("name","zxx"); multipartBodyBuilder.addFormDataPart("number","9527"); multipartBodyBuilder.addFormDataPart("country","China"); MultipartBody multipartBody=multipartBodyBuilder.build(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); requestBuilder.post(multipartBody); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG,"onFailure"); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG,"onResponse"); } }); }catch (Exception e){ } } }).start(); } } 请注意:测试时,请将url替换成您自己的可用地址 OkHttp拦截器 package com.cn.okhttp02; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import java.io.IOException; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** * 原创作者:谷哥的小弟 * 博客地址:http://blog.csdn.net/lfdfhl */ public class MainActivity extends AppCompatActivity { public final static String TAG="reborn"; private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); testApplicationInterceptors(); testNetworkInterceptors(); } private void init(){ mContext=this; } //测试Application Interceptors public void testApplicationInterceptors(){ new Thread(new Runnable() { @Override public void run() { try{ Log.i(TAG,"----> run"); String url="http://blog.csdn.net/lfdfhl"; OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder(); //添加应用拦截器 okHttpClientBuilder.addInterceptor(new LoggingInterceptor()); OkHttpClient okHttpClient=okHttpClientBuilder.build(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); requestBuilder.addHeader("os","Android"); requestBuilder.addHeader("country","China"); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG,"----> onFailure"); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG,"----> onResponse"); int code=response.code(); String result=response.body().string(); response.body().close(); Log.i(TAG,"测试Application Interceptors "+result); } }); }catch (Exception e){ } } }).start(); } //测试Network Interceptors public void testNetworkInterceptors(){ new Thread(new Runnable() { @Override public void run() { try{ Log.i(TAG,"----> run"); String url="http:www.github.com"; OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder(); //添加网络拦截器 okHttpClientBuilder.addNetworkInterceptor(new LoggingInterceptor()); OkHttpClient okHttpClient=okHttpClientBuilder.build(); Request.Builder requestBuilder=new Request.Builder(); requestBuilder.url(url); requestBuilder.addHeader("os","Android"); requestBuilder.addHeader("country","China"); Request request=requestBuilder.build(); Call call=okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.i(TAG,"----> onFailure"); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG,"----> onResponse"); int code=response.code(); String result=response.body().string(); response.body().close(); Log.i(TAG,"测试Network Interceptors "+result); } }); }catch (Exception e){ } } }).start(); } class LoggingInterceptor implements Interceptor { @Override public Response intercept(Interceptor.Chain chain) throws IOException { Log.i(TAG,"----> intercept"); Request request = chain.request(); long t1 = System.nanoTime(); Log.i(TAG, "intercept: " + String.format("Sending request %s on %s%n%s",request.url(), chain.connection(), request.headers())); Response response = chain.proceed(request); long t2 = System.nanoTime(); Log.i(TAG, "intercept: " + String.format("Received response for %s in %.1fms%n%s",response.request().url(), (t2 - t1) / 1e6d, response.headers())); return response; } } } 什么是拦截器呢? 拦截器能对Call进行监测、改写、重试连接;它能够对请求和响应进行二次加工。通俗地说:拦截器是请求和回复之间的一道门——发出请求时数据需要从这道门出去;接收响应时数据需要从这道门进来。当然,当数据(不论进出)经过这道门时,该门可对数据进行某些操作。 OkHttp3常用的拦截器分为: Application Interceptors 应用拦截器 Network Interceptors 网络拦截器 这两个拦截器有什么区别呢? Application interceptors 应用拦截器 Don’t need to worry about intermediate responses like redirects and retries. 不关心中间过程的响应,如重定向和重试 Are always invoked once, even if the HTTP response is served from the cache. 总是只调用一次,即使HTTP响应是从缓存中获取 Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match. 关注应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match. Permitted to short-circuit and not call Chain.proceed(). 允许短路且不调用Chain.proceed() Permitted to retry and make multiple calls to Chain.proceed(). 允许重试,多次调用 Chain.proceed() Network Interceptors 网络拦截器 Able to operate on intermediate responses like redirects and retries. 能够操作中间过程的响应,如重定向和重试. Not invoked for cached responses that short-circuit the network. 当网络短路返回缓存响应时不被调用 Observe the data just as it will be transmitted over the network. 只观察在网络上传输的数据. Access to the Connection that carries the request. 携带请求访问连接 拦截器使用场景 为request统一添加header 检查response判定用户登录信息是否失效,并用Dialog提示用户登录 重写响应头和改变响应体。但不是很推荐这么做,因为可能违反web服务器的期望。

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

深度学习鼻祖Geoffrey Hinton帮你入门带你飞

本文联合编译:Blake、高斐 雷锋网注:Geoffrey Everest Hinton(杰弗里·埃弗里斯特·辛顿)是一位英国出生的计算机学家和心理学家,以其在神经网络方面的贡献闻名。辛顿是反向传播算法和对比散度算法的发明人之一,也是深度学习的积极推动者,目前任职于多伦多大学与Google。作为人工智能领域的三位奠基人之一,早在30年前,辛顿就已经在深度学习领域留下了自己的烙印。然而,直到计算机的性能达到深度学习的要求,辛顿才开始在学术界以外得到自己应得的广泛认可,本文是他对于深度学习介绍的演讲PPT。 深度学习 Geoffrey Hinton 多伦多大学&Google 机器学习任务的频谱 典型的统计学方法 低维度数据(例如,低于1000个维度) 数据中存在大量的噪音

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

DBA入门之路:关于日常工作的建议

今天上午在恩墨学院进行了一个简短的分享,引用了多年前我的一页PPT,其中记录了我对DBA日常工作的建议。 虽然这7点内容来自多年以前的总结,但是在今天仍然具有指导意义,我稍微做了一点补充和修订,在此分享给大家。 我对其中几点再做一点展开阐释: 实时监控重要统计信息和等待事件 实时监控对于数据库运行至关重要、能够表征数据库重要变化的统计信息、等待事件,并且据此发送报警。这对于数据库的日常维护是非常重要的,关注重点,从细微变化中察知系统改变,这对于DBA来说是一项重要的素质要求。 而对于Stat和Wait信息,数据库中核心的、常见的指标并不多,作为DBA,可以从你能够列出的常见的10个统计数据、等待事件入手,针对性的进行深入、全面的学习,经过一段时间之后,必然有很多收获; 全面深入的了解应用架构 不了解应用的DBA是没有前途的DBA,对应用了解不深入的DBA算不上Expert,所以一定要深入了解应用。 这句话写自6年多以前,但是今天更加适用了,我们认为DBA应该向前走,才能发挥更大的价值,尤其是在互联网的时代,DevOps就是应用和运维结合的趋势和理念指引。 部署自动的AWR/ASH报告生成机制 对于管理众多数据库的DBA,每天应当检查前日的AWR,重点ASH、SQL报告,熟悉数据库的运行状况,做到对于数据库的了如指掌; 应当编写自动化脚本或部署工具,根据系统负载,找到那些在峰值消耗较高的报告点,重点关注其中可能存在的问题; 每天至少优化和熟悉一个Top SQL 根据AWR和SQL报告,每天至少了解或熟悉一个Top SQL,能优化的要提出优化和调整建议;这对于管理少量系统的DBA会特别有帮助,通过关注SQL,进一步了解业务逻辑,通过优化SQL,进一步改善性能,这些都会非常有助于DBA能力的提升; 对于哪些刚刚开始DBA生涯的朋友们,可以借鉴这一条的建议; 撰写系统架构、现状、调整备忘录 其实最后一条也是我非常重视的,实际上是锻炼和培养一个DBA的文档能力;根据对数据库的研究和了解,不断记录数据库的状况,撰写数据库架构、现状及调整备忘录,不放过任何可能的优化与改进的机会,也为调整和变化留下可查的依据。 这些关于DBA日常工作的建议,我总结出来,作为给初学者的指导,与大家分享。 文章转自数据和云公众号,原文链接

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册