Arganzheng's Blog

stay hungry, stay foolish

Andriod平台推送系统设计

背景 移动互联网带来一个结果就是实时性,而消息推送就是实时性的一个重要原因。服务器经常会推送各种消息给终端,比如最新的新闻,微博,评论,等等。可以说,主动消息推送是一个越来越基本的功能了。那么怎么实现呢? 常见的实现方案有如下几种: 1. 轮询方式(PULL) 应用程序周期性的与服务器进行连接并查询是否有新的消息。你必须自己实现和服务器之前的通信,例如消息队列。 主要要考虑轮询的效率,如果太慢可能导致某些消息的延迟。如果太快,则会消耗流量和电池电量。 2. SMS 在Android平台通过拦截SMS消息。这个方案很难找到免费的短消息发送网关,因此成本相对比较高。 3. 持久连接(PUSH) 客户端通过发送心跳包,和服务器维持一个TCP连接。这个方案可...

Spring各种依赖注入注解的区别

Spring对于Bean的依赖注入,支持多种注解方式: @Resource javax.annotation JSR250 (Common Annotations for Java) @Inject javax.inject JSR330 (Dependency Injection for Java) @Autowired org.springframework.bean.factory Spring 直观上看起来,@Autowired是Spring提供的注解,其他几个都是JDK本身内建的注解,Sp...

一个简单分页查询组件实现

背景 分页查询是非常常见的需求。所以有必要做成一个比较公用的组件,避免大家重复实现分页功能。 实现 分页组件分为前台部门和后台部分。这里先前台说起。 前台分页组件 因为我们的网站用的是bootstrap的样式,所以找了一个基于bootstrap的前台分页组件——bootstrap-paginator。使用非常简单,这里关键是用velocity的宏把它定义成一个组件: #macro(showPaginator $page) <div id="paginator"></div> <form id="form-paginator" style="display:none;" method="POST"> <...

优雅的Builder模式

Builder模式是GoF中的创建型设计模式中的一种。原来的意图是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。不过现在基本主要都是用于流水接口进行优雅构建。另外,在Groovy这样的动态语言中,是一种简单方便的DSL。下面分别介绍这两种场景。 流水接口 这个例子来源于笔者在做动态页面缓存需求时的一个实现。具体可以参见笔者的另一篇博文:动态页面缓存方案。其中应用控制静态页面的缓存机制可以通过如下两种方式控制: 对于静态的配置,可以使用@CacheControl注解进行配置。 @CacheControl(isPublic = true, maxAge = 300, sMaxAge = 300) 会自动生成:Cache-Co...

动态页面缓存方案

背景 像新闻等这样的比较少变化的页面,提供一个静态页面缓存机制,避免每次都动态拉取数据渲染生成HTML。 解决方案 总体原则 应用服务器(这里是tomcat)不处理静态资源的缓存,由前端nginx、CDN和browser来处理。应用通过HTTP头控制前端静态资源缓存的缓存时间和机制。应用服务器这边缓存的是数据(redis等cache),而不是静态页面。这样的好处是系统的边界和职责更加明确。原来的数据逻辑也不需要修改。也不需要再次实现一套静态资源缓存机制。 约定 只缓存GET请求 隐私内容不适合缓存。即对于同一个URL,不同用户看到的信息是不一样的。一般是通过cookies或者session来区分不同用户请求的。这种情况下不适合缓存,CDN缓存也...

小议Android手机隐私数据的存储安全

WhatsApp引出的隐私泄漏风险 刚被Facebook收购的WhatsApp最近可谓是不太平。安全服务厂商DoubleThink公司3月13号称,Android版WhatsApp中存在加密漏洞,允许另一应用访问并读取所有用户的聊天记录。尽管WhatsApp对Android版本进行了大的更新,但该漏洞仍然存在。导致漏洞的是因为Android版的WhatsApp聊天记录被存储在手机上的SD卡内,只要用户授权其他应用访问这些数据,这些聊天记录即可被任何Android应用读取。 Android的SD卡存储在 /sdcard 目录,仔细观察该目录权限设置,发现SD卡权限是777,也就是说,任何APP都可以读取其他APP保存在SD卡的文件。联系到前文说到恶意软件那么多,保...

使用zookeeper实现分布式锁

大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高。利用基于google chubby原理开发的开源的zookeeper,可以使得这个问题变得简单很多。下面介绍几种可能的实现方式,并且对比每种实现方式的优缺点。 1. 利用节点名称的唯一性来实现共享锁 ZooKeeper抽象出来的节点结构是一个和unix文件系统类似的小型的树状的目录结构。ZooKeeper机制规定:同一个目录下只能有一个唯一的文件名。例如:我们在Zookeeper目录/test目录下创建,两个客户端创建一个名为Lock节点,只有一个能够成功。 算法思路: 利用名称唯一性,加锁操作时,只需要所有客户端一起创...

ZooKeeper简介

Zookeeper的简介 ZooKeeper是一个构建在Paxos算法上的高可用的分布式数据管理与系统协调框架,提供了一系列原语集,更上层的应用可以用它来实现同步,配置管理,名称服务,Master选举,分布式锁,分布式队列等。 zookeeper提供如下服务保证 顺序一致性: client的updates请求都会根据它发出的顺序被顺序的处理 原子性: 一个update操作要么成功要么失败,没有其他可能的结果 一致性的镜像: client不论连接到哪个server,展示给它都是同一个视图 可靠性: 一旦一个update被应用就被持久化了,除非另一个update请求更新了当前值 及时性: 客户端所看到的系统在一个时间范围内是最新的 zoo...

开放平台鉴权以及OAuth2.0介绍

OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容。 OAuth 2.0不兼容1.0。 协议的参与者 RO (resource owner): 资源所有者,对资源具有授权能力的人。 RS (resource server): 资源服务器,它存储资源,并处理对资源的访问请求。 Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源。 AS (authorization server): 授权服务器,它认证RO的身份,为RO提供授权审批流程,并最终颁发授权令牌(Access Token)。 ...

闭包

匿名函数 (x: Double) => 3 * x 可以看到,函数就是接收输入,执行算法,返回结果。由于输入都是参数,所以函数其实是无状态的。 我们可以把这个函数存放在变量中: val triple = (x: Double) => 3 * x 这就跟你用def一样: def triple = (x: Double) => 3 * x 存放变量中就是命名函数。 匿名函数和命名函数都是对象,可以作为参数输入,也可以作为结果返回。 有状态的函数 上面的例子中,我们定义了一个算法(函数),它的作用是将输入参数乘以3。加入我们想让它变得更通用一些,可以对输入参数乘以y,也就是说,我们要定义这么一个函数: (x: Double) ...

×