参考文献: 当当开源文档
上篇文章已经创建了一个简单的demo了。
REST的优点:
- 可更高效利用缓存来提高响应速度
- 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
- 浏览器即可作为客户端,简化软件需求
- 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
- 不需要额外的资源发现机制
- 在软件技术演进中的长期的兼容性更好
使用场景:
- 跨语言调用: 前端WEB直接访问服务
- 开放平台API
-
企业内部不同平台调用
一处编写,到处调用
消费场景
- 非dubbo的消费端调用dubbo的REST服务(non-dubbo --> dubbo)
- dubbo消费端调用dubbo的REST服务 (dubbo --> dubbo)
- dubbo的消费端调用非dubbo的REST服务 (dubbo --> non-dubbo)
非dubbo消费端消费
创建SpringBoot工程,引入web依赖即可。这里使用了OKhttp3调用http请求所以依赖如下:
<dependency>
<groupId>com.zkdubbo</groupId>
<artifactId>zk-dubbo-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
demo :
@RestController
@RequestMapping("/hello")
public class HelloController {
@Value("${https.hello}")
private String url;
@GetMapping("/get")
public DubboResponse get(){
DubboResponse syncRequest = OKHttpUtils.getSyncRequest(url);
return syncRequest;
}
@PostMapping("/post")
public DubboResponse post(@RequestBody Object object){
return OKHttpUtils.postSyncRequest(url, object);
}
}
/**
* @author bertram.wang
* @sign 2019/7/7
* @desc Http调用工具
*/
public class OKHttpUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(OKHttpUtils.class);
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* 同步的GET调用
* @return
*/
public static DubboResponse getSyncRequest(String url){
LOGGER.info("GET 调用请求:{}", url);
Request request = new Request.Builder().get().url(url).build();
try {
Response response = HTTP_CLIENT.newCall(request).execute();
DubboResponse dubboResponse = OBJECT_MAPPER.readValue(response.body().bytes(), DubboResponse.class);
return dubboResponse;
} catch (IOException e) {
LOGGER.error("GET 调用请求:{}异常, 原因: {}", url, e.getMessage());
return DubboResponseBuild.fill(e.getMessage());
}
}
/**
* 同步的POST调用
* @return
*/
public static DubboResponse postSyncRequest(String url, Object data){
LOGGER.info("POST 调用请求:{}", url);
try {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), OBJECT_MAPPER.writeValueAsString(data));
Request request = new Request.Builder().post(requestBody).url(url).build();
Response response = HTTP_CLIENT.newCall(request).execute();
DubboResponse dubboResponse = OBJECT_MAPPER.readValue(response.body().bytes(), DubboResponse.class);
return dubboResponse;
} catch (IOException e) {
LOGGER.error("POST 调用请求:{}异常, 原因: {}", url, e.getMessage());
return DubboResponseBuild.fill(e.getMessage());
}
}
}
server:
port: 8880
https:
hello: http://127.0.0.1:20880/servers/zkDubboServer/hello
非常简单的一个消费demo。
消费者日志
服务提供者日志
服务提供者会发送MQ消息并消费。
@Override
public DubboResponse hello() {
try {
kafkaProducer.send("测试发送MQ");
} catch (Exception e) {
return DubboResponseBuild.fill(e.getMessage());
}
return DubboResponseBuild.success();
}
@Component
public class MyKafkaProducer<T> {
@Resource
private KafkaTemplate<String, T> kafkaTemplate;
public void send(T message) throws Exception{
kafkaTemplate.send("bertram.topic", message);
}
}
@Component
public class KafkaConsumer {
@KafkaListener(topics = "bertram.topic")
public void listen (ConsumerRecord<?, ?> record) throws Exception {
System.out.printf("topic = %s, offset = %d, value = %s \n", record.topic(), record.offset(), record.value());
}
}