2016年1月28日星期四

Hystrix介绍

Hystrix

What Is Hystrix For?

Hystrix is designed to do the following:

  • Give protection from and control over latency and failure from dependencies accessed (typically over the network) via third-party client libraries. 让程序具有处理调用外部服务失败的能力
  • Stop cascading failures in a complex distributed system.
  • Fail fast and rapidly recover.
  • Fallback and gracefully degrade when possible.
  • Enable near real-time monitoring, alerting, and operational control.

Hystrix works by:

  • Preventing any single dependency from using up all container (such as Tomcat) user threads.
  • Shedding load and failing fast instead of queueing.
  • Providing fallbacks wherever feasible to protect users from failure.
  • Using isolation techniques (such as bulkhead, swimlane, and circuit breaker patterns) to limit the impact of any one dependency.
  • Optimizing for time-to-discovery through near real-time metrics, monitoring, and alerting
  • Optimizing for time-to-recovery by means of low latency propagation of configuration changes and support for dynamic property changes in most aspects of Hystrix, which allows you to make real-time operational modifications with low latency feedback loops.
  • Protecting against failures in the entire dependency client execution, not just in the network traffic.

Hystrix使用命令模式HystrixCommand(Command)包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行

Hello World

下面是一个HystrixCommand的简单的“hello world”实现

1.public class CommandHelloWorld extends HystrixCommand<String> {
2. private final String name;
3. public CommandHelloWorld(String name) {
4. super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
5. this.name = name;
6. }
7. @Override
8. protected String run() {
9. // a real example would do work like a network call here
10. return "Hello " + name + "!";
11. }
12.}

同步执行

Hystrix commands能通过execute()方法调用被同步的执行

1.String s = new CommandHelloWorld("World").execute();

异步执行

异步执行通过调用queue()方法实现

1.Future<String> fs = new CommandHelloWorld("World").queue();

响应式执行

响应式执行(异步回调)通过使用observe() 执行

1.Observable<String> fs = new CommandHelloWorld("World").observe();

返回值可以通过订阅Observable获得

1.fs.subscribe(new Action1<String>() {
2. @Override
3. public void call(String s) {
4. // value emitted here
5. }
6.});

Fallback

优美的降级可以通过增加一个getFallback()实现来达到。该方法在各种类型的失败后执行。如: run()方
法调用失败,超时,线程池,信号丢弃以及熔断器短路。

1.     @Override
2. protected String getFallback() {
3. return "Hello Failure " + name + "!";
4. }

错误传播

从run()方法中抛出的所以异常(除了HystrixBadRequestException)都被计为异常。将触发getFallback()
和熔断逻辑。在HystrixBadRequestException中抛出的例外,你可以根据你的喜好进行包装,然后通过
getCause()获取。
HystrixBadRequestException设计的使用场景为,报告不合法的参数或非系统性错误。这些都不能计入失
败次数的度量,也不应当触发回退逻辑

Command Name

Command Group

group进行统一管理
command组键名被用于将command分组,如报表,警告,面板或者组包的所以者。
默认情况下,它被用于command的线程池的命名,除非有单独的定义

1.private static final Setter cachedSetter = 
2. Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
3. .andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"));
4.
5. public CommandHelloWorld(String name) {
6. super(cachedSetter);
7. this.name = name;
8. }

Command线程池

线程池的键被用于监控HystrixThreadPool时的呈现,度量的发布,缓存等其它应用。一个
HystrixCommand 是和一个单个的HystrixThreadPool相关联,通过注入它的HystrixThreadPoolKey可以取
得HystrixThreadPool 或者它默认情况下用HystrixCommandGroupKey创建一个。

请求缓存

请求缓存通过实现HystrixCommand或者HystrixObservableCommand中的getCacheKey()方法完成:依赖于request context 的某些东西,必须实例化HystrixRequestContext

1.public class CommandUsingRequestCache extends HystrixCommand<Boolean> {
2.
3. private final int value;
4.
5. protected CommandUsingRequestCache(int value) {
6. super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
7. this.value = value;
8. }
9.
10. @Override
11. protected Boolean run() {
12. return value == 0 || value % 2 == 0;
13. }
14.
15. @Override
16. protected String getCacheKey() {
17. return String.valueOf(value);
18. }
19.}

请求合并

请求合并是一个特性,它能自动将一批请求合并到单一的HystrixCommand实例中执行。
可以设定批次的大小和时间作为促发器来执行一个批次
两种style的请求合并

  • request-scoped
  • globally-scoped.
    This is configured at collapser construction, and defaulted to request-scoped.

Request Context Setup

为了能使用request的scoped特性(请求缓存,请求折叠,请求日记)HystrixRequestContext 的生命周期
必须被管理起来。(或者一个替代的HystrixConcurrencyStrategy 实现)
这就意味着下面代码必须在一个请求之前执行

1.HystrixRequestContext context = HystrixRequestContext.initializeContext();

然后在请求的最后调用

1.context.shutdown();

常见模式

快速失败 Fail Fast

无声失败 Fail Silent

无声的失败等同于返回一个空的响应或者删除功能,它通过返回null,空的map对象,空的list或者其他类似
的响应实现。 通常通过HystrixCommand实例中的getFallback() 方法实现

回退:静态的 Fallback:Static

一些回退能返回在代码中硬编码的值。它不能引起特性或将被移除服务(如同无声失败经常处理的方
法),但是执行默认的行为逻辑。

Fallback: Stubbed

一个存根回退典型的被用于包含多个字段的一个组合对象被返回时。它们其中的一部分能被其它请求状态
来决定。当其它字段被设置为默认值。

Fallback: Cache via Network

由于回退如果重掉网络可能导致另外的失败,因此需要通过另外的HystrixCommand转换。
另外重要的是,回退command应当在独立的线程池中执行。如果两个command共享相同的线程池,会导
致主command将变的延迟并且占用整个的线程池,从而阻止回退。

主从都失效

enter image description here
通过两个Command进行隔离

Client Doesn’t Perform Network Access

迁移

enter image description here
to
enter image description here

MySQL主备同步方案

MySQL主备同步方案 http://mysqllover.com/?p=810 http://mysqllover.com/?p=1370 https://yq.aliyun.com/articles/3022

Scala的反射机制

Scala的反射机制

Scala的反射机制

  1. Manifest & ClassManifest
    Manifest是在编译时捕捉的,编码了“捕捉时”所致的类型信息。然后就可以在运行时检查和使用类型信息,但是manifest只能捕捉当Manifest被查找时在隐式作用域里的类型。
1.def first[A : ClassManifest](x:Array[A]) = Arraay(x(0))
  1. ClassTag & TypeTag
    scala在2.10里却用TypeTag替代了Manifest,用ClassTag替代了ClassManifest,原因是在路径依赖类型中,Manifest存在问题:
1.scala> class Foo{class Bar}
2.

3.scala> def m(f: Foo)(b: f.Bar)(implicit ev: Manifest[f.Bar]) = ev
4.
5.scala> val f1 = new Foo;val b1 = new f1.Bar
6.scala> val f2 = new Foo;val b2 = new f2.Bar
7.
8.scala> val ev1 = m(f1)(b1)
9.ev1: Manifest[f1.Bar] = Foo@681e731c.type#Foo$Bar
10.
11.scala> val ev2 = m(f2)(b2)
12.ev2: Manifest[f2.Bar] = Foo@3e50039c.type#Foo$Bar
13.
14.scala> ev1 == ev2 // they should be different, thus the result is wrong
15.res28: Boolean = true

ev1 不应该等于 ev2 的,因为其依赖路径(外部实例)是不一样的。
还有其他因素,所以在2.10版本里,使用 TypeTag 替代了 Manifest
TypeTag:由编辑器生成,只能通过隐式参数或者上下文绑定获取
可以有两种方式获取:

1.scala> import scala.reflect.runtime.universe._
2.import scala.reflect.runtime.universe._
3.
4.//使用typeTag
5.scala> def getTypeTag[T:TypeTag](a:T) = typeTag[T]
6.getTypeTag: [T](a: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]
7.
8.//使用implicitly 等价的
9.//scala>def getTypeTag[T:TypeTag](a:T) = implicitly[TypeTag[T]]
10.
11.scala> getTypeTag(List(1,2,3))
12.res0: reflect.runtime.universe.TypeTag[List[Int]] = TypeTag[List[Int]]
13.

通过TypeTag的tpe方法获得需要的Type(如果不是从对象换取Type 而是从class中获得 可以直接用 typeOf[类名])

  1. 反射获取TypeTag和ClassTag
    String———->Calss————–>Manifest——–>TypeTag
    Class.forName ManifestFactory.classType scala.reflect.runtime.universe.manifestToTypeTag
1.import scala.reflect.runtime.universe
2.import scala.reflect.ManifestFactory
3.
4.val className = "java.lang.String"
5.val mirror = universe.runtimeMirror(getClass.getClassLoader)
6.val cls = Class.forName(className)
7.val t = universe.manifestToTypeTag(mirror, ManifestFactory.classType(cls))

MySQL优化

MySQL优化

MySQL优化

OPTIMIZE

1.REPAIR TABLE `table_name` 修复表 
2.OPTIMIZE TABLE `table_name` 优化表

  • REPAIR TABLE 用于修复被破坏的表。
  • OPTIMIZE TABLE 用于回收闲置的数据库空间,当表上的数据行被删除时,所占据的磁盘空间并没有立即被回收,使用了OPTIMIZE TABLE命令后这些空间将被回收,并且对磁盘上的数据行进行重排(注意:是磁盘上,而非数据库)。多数时间并不需要运行OPTIMIZE TABLE,只需在批量删除数据行之后,或定期(每周一次或每月一次)进行一次数据表优化操作即可,只对那些特定的表运行。

OPTIMIZE TABLE对InnoDB 和 MyISAM相关知识

  1. InnoDB 和 MyISAM
    目前支持optimize命令的引擎有 MyISAM, InnoDB, and ARCHIVE,对于InnoDB,会将optimize命令映射为ALTER TABLE命令,该命令会重建数据表,更新索引统计信息、回收主键索引中空间。
  2. InnoDB 和 MyISAM
    如果你的MySQL是有备库的,如果你只希望在主库上执行的话,那么可以加上关键字NO_WRITE_TO_BINLOG(或者LOCAL,意思完全相同)。
1.OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE

MySQL内存表&临时表

内存表::http://www.nowamagic.net/librarys/veda/detail/1405 临时表: http://tech.uc.cn/?p=2218

2016年1月8日星期五

xml中的特殊字符

xml中的特殊字符

xml中的特殊字符

下面的字符在 [XML]中被定义为 空白(whitespace)字符:

1.空格 (&#x0020;) 
2.Tab (&#x0009;)
3.回车 (&#x000D;)
4.换行 (&#x000A;)