
🔎这里是【微服务~远程调用】,关注我学习云原生不迷路
👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️
【微服务~远程调用】 目前主要更新微服务,一起学习一起进步。
本期主要介绍微服务~远程调用
2个团队,分别开发了“商品管理系统”和“用户管理系统”

问题:“商品管理系统”需要使用“用户管理系统”某个功能,怎么办?
根据用户的会员等级,显示不同的打折

客户端程序通过接口调用服务端程序,并获得该服务返回的数据的过程,称为远程调用。
“商品管理系统”调用“用户管理系统”的过程,就是“远程调用”。此时“商品管理系统”相当于模拟“浏览器”。

常见的远程调用方式有2种:
RPC:Remote Produce Call远程过程调用,==自定义数据==格式的远程调用方式。基于原生TCP通信,速度快,效率高。
Http:采用http协议远程调用方式,==规定==了数据传输的格式,缺点是消息封装臃肿。现在热门的Rest风格,就可以通过http协议来实现。
常见框架 :
RPC常见框架: dubbo、WebService
Http常见框架:HttpClient、RestTemplate
| 区别 | HTTP | RPC |
|---|---|---|
| 速度 | 较慢 | 快 |
| 难度 | 简单 | 复杂 |
| 灵活性 | 灵活,跨平台、跨语言 |
如何选择
那么我们该怎么选择呢?
==微服务==,基于Spring Cloud的微服务,更加强调的是独立、自治、灵活,一般都会采用基于Http的Rest风格服务。

项目名:nacos-parent-2.1
添加坐标:
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>2.3.5.RELEASE</version>
</parent>
<properties>
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.7-SNAPSHOT</spring.cloud.alibaba.version>
<mybatis.plus.starter.version>3.4.0</mybatis.plus.starter.version>
<durid.starter.version>1.1.10</durid.starter.version>
<swagger.version>2.7.0</swagger.version>
<jwt.jjwt.version>0.9.0</jwt.jjwt.version>
<jwt.joda.version>2.9.7</jwt.joda.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.plus.starter.version}</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${durid.starter.version}</version>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
项目:nacos-data
添加依赖
<dependencies>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--支持lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
server:
port: 7778
拷贝BaseResult 和 Swagger2ConfigurationV3
编写启动类
package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Created by liangtong.
*/
@SpringBootApplication
public class DataApplication {
public static void main(String[] args) {
SpringApplication.run(DataApplication.class, args);
}
}
创建JavaBean
package com.czxy.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Created by liangtong.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer uid;
private String username;
private String password;
private Integer age;
}
package com.czxy.controller;
import com.czxy.domain.User;
import com.czxy.vo.BaseResult;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by liangtong.
*/
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping
public BaseResult findAll(){
List<User> list = new ArrayList<>();
list.add(new User(1,"jack","1234",18));
list.add(new User(2,"rose","5678",21));
list.add(new User(3,"tom","6666",25));
return BaseResult.ok("查询所有",list);
}
@GetMapping("/{uid}")
public BaseResult findById(@PathVariable("uid")Integer uid){
User user = new User(1,"jack","1234",18);
return BaseResult.ok("查询成功",user);
}
@GetMapping("/search")
public BaseResult search(User user){
System.out.println(user);
return BaseResult.ok("查询成功",user);
}
@PostMapping
public BaseResult save(@RequestBody User user){
System.out.println(user);
// return ResponseEntity.status(302).body(BaseResult.ok("添加成功"));
return BaseResult.ok("添加成功");
}
@PutMapping
public BaseResult update(@RequestBody User user){
System.out.println(user);
return BaseResult.ok("更新成功");
}
@DeleteMapping("/{uid}")
public BaseResult deleteById(@PathVariable("uid")Integer uid){
System.out.println(uid);
return BaseResult.ok("删除成功");
}
}
HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
创建项目:nacos-http
pom配置
<dependencies>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<!--支持lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HttpApplication {
public static void main(String[] args) {
SpringApplication.run(HttpApplication.class, args);
}
}
package com.czxy;
public class TestHttp {
}
以get请求的方式,获得所有结果
1.创建客户端 (相当于打开浏览器)。CloseableHttpClient
2.创建GET请求实例(确定访问路径) HTTPGet
3.发送请求(回车访问)execute
4.判断响应的状态码200
5.通过工具处理响应内容
6.关闭资源
@Test
public void testFindAll() {
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpGet httpGet = new HttpGet("http://localhost:7778/user");
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode() == 200) {
String str = EntityUtils.toString(response.getEntity());
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}

@Test
public void testFindId() {
String id = "1";
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpGet httpGet = new HttpGet("http://localhost:7778/user/" + id);
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode() == 200) {
String str = EntityUtils.toString(response.getEntity(),"UTF-8");
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
基本使用
@Test
public void testDemo03(){
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
StringBuilder params = new StringBuilder();
params.append("username=张三");
params.append("&");
params.append("password=1234");
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpGet httpGet = new HttpGet("http://localhost:7778/user/search" + "?" + params.toString());
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode() == 200){
// 3.1 获得响应数据的类型
System.out.println(response.getEntity().getContentType());
// 3.2 获得响应体内容
String str = EntityUtils.toString(response.getEntity(),"UTF-8");
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
拼凑特殊数据:URL中的特殊符号,需要使用URLEncoder处理
@Test
public void testDemo04(){
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
StringBuilder params = new StringBuilder();
params.append("username=" + URLEncoder.encode("&","UTF-8"));
params.append("&");
params.append("password=1234");
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpGet httpGet = new HttpGet("http://localhost:7778/user/search" + "?" + params.toString());
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode() == 200){
// 3.1 获得响应数据的类型
System.out.println(response.getEntity().getContentType());
// 3.2 获得响应体内容
String str = EntityUtils.toString(response.getEntity(),"UTF-8");
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testInsert() {
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpPost httpPost = new HttpPost ("http://localhost:7778/user/");
// 2.1 准备json数据
String jsonStr = "{\n" +
" \"uid\": \"1\",\n" +
" \"username\": \"jack\",\n" +
" \"password\": \"1234\",\n" +
" \"age\": \"18\"\n" +
" }";
// 2.2 设置请求体
httpPost.setEntity(new StringEntity(jsonStr,"UTF-8"));
// 2.3 设置请求数据类型为json
httpPost.setHeader("content-type","application/json;charset=UTF-8");
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == 200) {
String str = EntityUtils.toString(response.getEntity(),"UTF-8");
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
fastjson 是阿里巴巴提供最快的json转换工具
如果要使用fastjson,修改pom.xml文件,添加坐标(如果已有,忽略此步)
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
拷贝JavaBean:User
代码
@Test
public void testInsert2() {
try {
//1 创建Httpclient对象,相当于打开了浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
//2 确定请求方式和请求路径,相当于在浏览器输入地址
HttpPost httpPost = new HttpPost ("http://localhost:7778/user/");
// 2.1 准备json数据
User user = new User(1,"jack","1234",18);
String jsonStr = JSON.toJSONString(user);
// 2.2 设置请求体
httpPost.setEntity(new StringEntity(jsonStr,"UTF-8"));
// 2.3 设置请求数据类型为json
httpPost.setHeader("content-type","application/json;charset=UTF-8");
//3 执行请求并获取响应,相当于敲完地址后按下回车。
CloseableHttpResponse response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == 200) {
String str = EntityUtils.toString(response.getEntity(),"UTF-8");
System.out.println(str);
}
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg