最近几年, reactive programming这个词语的热度迅速提升,Wikipedia 上的 reactive programming 解释是 reactive programming is a programming paradigm oriented around data flows and the propagation of change. Dubbo3.0会实现Reactive Stream 的 rx 接口,从而能让用户享受到RP带来的响应性提升,甚至面向 RP 的架构升级。当然,我们希望 reactive 不单单能够带来事件(event)驱动的应用集成方式的升级,也希望在 Load Balance(选择最优的服务节点),fault tolerance(限流降级时最好做到自适应)等方面发挥其积极价值。
关于流程图中提到的 Result,Result 在 Dubbo 的一次 RPC 调用中代表返回结果,在 3.0 中 Result 自身增加了代表状态的接口,类似 Future 现在 Result 可以代表一次未完成的调用。
要让 Result 具备代表异步返回结果的能力,有两中方式来实现:
1. Result is a Future,在 Java 8 中更合理的方式是继承 CompletionStage 接口。
public interface Result extends CompletionStage {
}
2. 让 Result 实例持有 Future 实例,与 1 的区别即是设计中选用“继承”还是“组合”。
public class AsyncRpcResult implements Result {
private CompletableFuture resultFuture;
}
同时,为了让 Result 更直观的体现其异步结果的特性,也为了方便面向 Result 接口编程,我们可以考虑为Result增加一些异步接口:
public interface Result extends Serializable {
Result thenApplyWithContext(Function fn);
CompletableFuture thenApply(Function fn);
Result get() throws InterruptedException, ExecutionException;
}
public class DemoServiceImpl implements DemoService {
@Override
public Mono requestMonoWithMonoArg(Mono m1, Mono m2) {
return m1.zipWith(m2, new BiFunction() {
@Override
public String apply(String s, String s2) {
return s+" "+s2;
}
});
}
@Override
public Flux requestFluxWithFluxArg(Flux f1, Flux f2) {
return f1.zipWith(f2, new BiFunction() {
@Override
public String apply(String s, String s2) {
return s+" "+s2;
}
});
}
}
然后配置并启动服务端,注意协议名字填写 rsocket:
public class RsocketProvider {
public static void main(String[] args) throws Exception {
new EmbeddedZooKeeper(2181, false).start();
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/rsocket-provider.xml"});
context.start();
System.in.read(); // press any key to exit
}
}
然后配置并启动消费者消费者如下, 注意协议名填写 rsocket:
public class RsocketConsumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/rsocket-consumer.xml"});
context.start();
DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
while (true) {
try {
Mono monoResult = demoService.requestMonoWithMonoArg(Mono.just("A"), Mono.just("B"));
monoResult.doOnNext(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
}).block();
Flux fluxResult = demoService.requestFluxWithFluxArg(Flux.just("A","B","C"), Flux.just("1","2","3"));
fluxResult.doOnNext(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
}).blockLast();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
}
web.xml报错
The content of element type "web-app" must match "(icon?,display-
name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,s
JUnit4:Test文档中的解释:
The Test annotation supports two optional parameters.
The first, expected, declares that a test method should throw an exception.
If it doesn't throw an exception or if it
借鉴网上的思路,用java实现:
public class NoIfWhile {
/**
* @param args
*
* find x=1+2+3+....n
*/
public static void main(String[] args) {
int n=10;
int re=find(n);
System.o
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
分析:这是不同系统编码格式引起的:在windows系统中编辑的.sh文件可能有不可见字符,所以在Linux系统下执行会报以上异常信息。
解决:
1)在windows下转换:
利用一些编辑器如UltraEdit或EditPlus等工具
Binary search tree works well for a wide variety of applications, but they have poor worst-case performance. Now we introduce a type of binary search tree where costs are guaranteed to be loga