经常使用RestTemplate (经常使用人体润滑剂的危害)
1、简介
在Spring-Boot名目开发中,当本模块的代码须要访问外面模块接口,或外部url链接的需求的时刻,须要经常使用网络衔接调用,上方提供了四种形式(扫除dubbo的形式)供大家选用。
形式一:经常使用OKHttp
网上关于OkHttp关系的引见如下!
经常使用OkHttp的关键长处:
目前OkHttp在开源名目中被宽泛经常使用,同时也是Retrofit、Picasso等库的外围库。springboot曾经很好地支持okhttp库。
2.1、参与依赖包
在经常使用之前,咱们须要先导入okhttp依赖包,不同的版本号,关系api稍有区别,本次引见的api操作基于3.14.9版本号。
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.9</version></dependency>
2.2、get同步恳求
okhttp动员get同步恳求十分的繁难,只有要几行代码就可以搞定。
案例如下!
Stringurl="https://www.bdu.com/";OkHttpClientclient=newOkHttpClient();//性能GET恳求Requestrequest=newRequest.Builder().url(url).get().build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//打印前往结果System.out.println(response.body().string());}catch(Exceptione){e.printStackTrace();}
2.3、post表单同步恳求
okhttp动员post表单格局的数据提交,同步恳求编程也十分的繁难,只有要几行代码就可以搞定。
案例如下!
Stringurl="https://www.baidu.com/";OkHttpClientclient=newOkHttpClient();//性能POST+FORM格局数据恳求RequestBodybody=newFormBody.Builder().add("userName","zhangsan").add("userPwd","123456").build();Requestrequest=newRequest.Builder().url(url).post(body).build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//打印前往结果System.out.println(response.body().string());}catch(Exceptione){e.printStackTrace();}
2.4、post表单+文件上行,同步恳求
假设在动员表单恳求的时刻,还须要上行文件,该如何成功呢?
案例如下!
Stringurl="https://www.baidu.com/";OkHttpClientclient=newOkHttpClient();//要上行的文件Filefile=newFile("/doc/Downloads/429545913565844e9b26f97dbb57a1c3.jpeg");RequestBodyfileBody=RequestBody.create(MediaType.parse("image/jpg"),file);//表单+文件数据提交RequestBodymultipartBody=newMultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("userName","zhangsan").addFormDataPart("userPwd","123456").addFormDataPart("userFile","00.png",fileBody).build();Requestrequest=newRequest.Builder().url(url).post(multipartBody).build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//打印前往结果System.out.println(response.body().string());}catch(Exceptione){e.printStackTrace();}
2.5、post+json数据,同步恳求
okhttp动员post+json格局的数据提交,同步恳求编程也很繁难。
案例如下!
MediaTypecontentType=MediaType.get("lication/json;charset=utf-8");Stringurl="https://www.baidu.com/";Stringjson="{}";OkHttpClientclient=newOkHttpClient();//性能POST+JSON恳求RequestBodybody=RequestBody.create(contentType,json);Requestrequest=newRequest.Builder().url(url).post(body).build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//打印前往结果System.out.println(response.body().string());}catch(Exceptione){e.printStackTrace();}
2.5、文件下载,同步恳求
文件下载,通常是get形式恳求,只有要在照应端经常使用字节流接受数据即可!
案例如下
publicstaticvoidmain(String[]args){//指标存储文件StringtargetFile="/doc/Downloads/1.png";//须要下载的原始文件Stringurl="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";OkHttpClientclient=newOkHttpClient();//性能GET恳求Requestrequest=newRequest.Builder().url(url).build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//失掉文件字节流byte[]stream=response.body().bytes();//写入指标文件writeFile(targetFile,stream);}catch(Exceptione){e.printStackTrace();}}/***写入指标文件*@paramtargetFile*@paramstream*@throwsIOException*/privatestaticvoidwriteFile(StringtargetFile,byte[]stream)throwsIOException{StringfilePath=StringUtils.substringBeforeLast(targetFile,"/");PathfolderPath=Paths.get(filePath);if(!Files.exists(folderPath)){Files.createDirectories(folderPath);}PathtargetFilePath=Paths.get(targetFile);if(!Files.exists(targetFilePath)){Files.write(targetFilePath,stream,StandardOpenOption.CREATE);}}
2.6、其余形式的同步恳求
在实践的名目开发中,有的接口须要经常使用put或许delete形式恳求,应该如何处置呢?
put形式恳求,案例如下!
//只有要在Request性能类中,换成put形式即可Requestrequest=newRequest.Builder().url(url).put(body).build();
雷同的,delete形式恳求也相似,案例如下!
//只有要在Request性能中,换成delete形式即可Requestrequest=newRequest.Builder().url(url).delete(body).build();
2.7、自定义参与恳求头部
大局部的时刻,基于安保的思考,很多时刻咱们须要把关系的鉴权参数放在恳求头部,应该如何处置呢?
以post+json格局恳求为例,参与头部恳求参数,案例如下!
MediaTypecontentType=MediaType.get("application/json;charset=utf-8");Stringurl="https://www.baidu.com/";Stringjson="{}";OkHttpClientclient=newOkHttpClient();//性能header头部恳求参数Headersheaders=newHeaders.Builder().add("token","11111-22222-333").build();//性能POST+JSON恳求RequestBodybody=RequestBody.create(contentType,json);Requestrequest=newRequest.Builder().url(url).headers(headers).post(body).build();//动员同步恳求try(Responseresponse=client.newCall(request).execute()){//打印前往结果System.out.println(response.body().string());}catch(Exceptione){e.printStackTrace();}
2.8、动员异步恳求
在上文中咱们引见的都是同步恳求,在最开局咱们也说到OkHttp不只支持同步伐用,也异步伐用,那么如何启动异步恳求编程呢?
其实操作很繁难,案例如下!
Stringurl="https://www.baidu.com/";OkHttpClientclient=newOkHttpClient().newBuilder().build();Requestrequest=newRequest.Builder().url(url).get().build();//动员异步恳求client.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(Callcall,IOExceptione){System.out.println("恳求意外+"+e.getMessage());}@OverridepublicvoidonResponse(Callcall,Responseresponse)throwsIOException{System.out.println("恳求成功,前往结果:"+response.body().string());}});
形式二:经常使用原始httpClient恳求
经常使用httpclient库。
/**@descriptionget形式失掉入参,拔出数据并动员流程*@authorly*@paramsdocumentId*@returnString*///@RequestMapping("/submit/{documentId}")publicStringsubmit1(@PathVariableStringdocumentId)throwsParseException{//此处将要发送的数据转换为json格局字符串Map<String,Object>map=task2Service.getMap(documentId);StringjsonStr=JSON.toJSONString(map,SerializerFeature.WRITE_MAP_NULL_FEATURES,SerializerFeature.QuoteFieldNames);JSONObjectjsonObject=JSON.parbject(jsonStr);JSONObjectsr=task2Service.doPost(jsonObject);returnsr.toString();}
/**@description经常使用原生httpClient调用外部接口*@authorly*@paramsdate*@returnJSONObject*/publicstaticJSONObjectdoPost(JSONObjectdate){String;CloseableHttpClientclient=HttpClients.createDefault();//要调用的接口urlStringurl="http://39.103.201.110:30661/xdap-open/open/process/v1/submit";HttpPostpost=newHttpPost(url);JSONObjectjsonObject=null;try{//创立恳求体并参与数据StringEntitys=newStringEntity(date.toString());//此处相当于在header外头参与content-type等参数s.setContentType("application/json");s.setContentEncoding("UTF-8");post.setEntity(s);//此处相当于在Authorization外头参与Beartoken参数消息post.addHeader("Authorization","Bearer"+assessToken);HttpResponseres=client.execute(post);Stringresponse1=EntityUtils.toString(res.getEntity());if(res.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//前往json格局:Stringresult=EntityUtils.toString(res.getEntity());jsonObject=JSONObject.parseObject(result);}}catch(Exceptione){thrownewRuntimeException(e);}returnjsonObject;}
、形式三:经常使用RestTemplate方法
Spring-Boot开发中,RestTemplate雷同提供了对外访问的接口API,这里关键引见Get和Post方法的经常使用。
Get恳求
提供了getForObject、getForEntity两种形式,其中getForEntity如下三种方法的成功:
Get--getForEntity,存在以下两种形式重载
1.getForEntity(Stringurl,ClassresponseType,Object…urlVariables)2.getForEntity(URIurl,ClassresponseType)
Get--getForEntity(URIurl,ClassresponseType)
//该方法经常使用URI对象来代替之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDKjava包下的一个类,示意一个一致资源标识符(UniformResourceIdentifier)援用。参考如下:RestTemplaterestTemplate=newRestTemplate();UriComponentsuriComponents=UriComponentsBuilder.fromUriString("http://USER-SERVICE/user?name={name}").build().expand("dodo").encode();URIuri=uriComponents.toUri();ResponseEntityresponseEntity=restTemplate.getForEntity(uri,String.class).getBody();
Get--getForObject,存在以下三种形式重载
1.getForObject(Stringurl,ClassresponseType,Object...urlVariables)2.getForObject(Stringurl,ClassresponseType,MapurlVariables)3.getForObject(URIurl,ClassresponseType)
getForObject方法可以了解为对getForEntity的进一步封装,它经过HttpMessageConverterExtractor对HTTP的恳求照应体body内容启动对象转换,成功恳求间接前往包装好的对象内容。
Post恳求
Post恳求提供有postForEntity、postForObject和postForLocation三种形式,其中每种形式都有三种方法,上方引见postForEntity的经常使用方法。
Post--postForEntity,存在以下三种形式重载
1.postForEntity(Stringurl,Objectrequest,ClassresponseType,Object...uriVariables)2.postForEntity(Stringurl,Objectrequest,ClassresponseType,MapuriVariables)3.postForEntity(URIurl,Objectrequest,ClassresponseType)
如下仅展示第二种重载形式
/**@descriptionpost形式失掉入参,拔出数据并动员流程*@authorly*@params*@return*/@PostMapping("/submit2")publicObjectinsertFinanceCompensation(@RequestBodyJSONObjectjsonObject){StringdocumentId=jsonObject.get("documentId").toString();returntask2Service.submit(documentId);}
/**@description经常使用restTimeplate调外部接口*@authorly*@paramsdocumentId*@returnString*/publicStringsubmit(StringdocumentId){String;RestTemplaterestTemplate=newRestTemplate();//创立恳求头HttpHeadershttpHeaders=newHttpHeaders();//此处相当于在Authorization外头参与Beartoken参数消息httpHeaders.add(HttpHeaders.AUTHORIZATION,"Bearer"+assessToken);//此处相当于在header外头参与content-type等参数httpHeaders.add(HttpHeaders.CONTENT_TYPE,"application/json");Map<String,Object>map=getMap(documentId);StringjsonStr=JSON.toJSONString(map);//创立恳求体并参与数据HttpEntity<Map>httpEntity=newHttpEntity<Map>(map,httpHeaders);Stringurl="http://39.103.201.110:30661/xdap-open/open/process/v1/submit";ResponseEntity<String>forEntity=restTemplate.postForEntity(url,httpEntity,String.class);//此处三个参数区分是恳求地址、恳求体以及前往参数类型returnforEntity.toString();}
、形式四:经常使用Feign启动生产
在maven名目中参与依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><version>1.2.2.RELEASE</version></dependency>
启动类上加上@EnableFeignClients
@SpringBootApplication@EnableFeignClients@ComponentScan(basePackages={"com.definesys.mpaas","com.xdap.*","com.xdap.*"})publicclassMobilecardApplication{publicstaticvoidmain(String[]args){SpringApplication.run(MobilecardApplication.class,args);}}
此处编写接口模拟外部接笔供feign调用外部接口形式经常使用
定义controller
@AutowiredPrintServiceprintService;@PostMapping("/outSide")publicStringtest(@RequestBodyTestDtotestDto){returnprintService.print(testDto);}
定义service
@ServicepublicinterfacePrintService{publicStringprint(TestDtotestDto);}
定义serviceImpl
publicclassPrintServiceImplimplementsPrintService{@OverridepublicStringprint(TestDtotestDto){return"模拟外部系统的接口性能"+testDto.getId();}}
构建Feigin的Service
定义service
//此处name须要设置不为空,url须要在.properties中设置@Service@FeignClient(url="${outSide.url}",name="service2")publicinterfaceFeignService2{@RequestMapping(value="/custom/outSide",method=RequestMethod.POST)@ResponseBodypublicStringgetMessage(@Valid@RequestBodyTestDtotestDto);}
定义controller
@AutowiredFeignService2feignService2;//测试feign调用外部接口入口@PostMapping("/test2")publicStringtest2(@RequestBodyTestDtotestDto){returnfeignService2.getMessage(testDto);}
postman测试
此处由于我经常使用了所在名目,所以须要参与肯定的恳求头号消息,关于Feign的恳求头参与也会在后续补充
补充如下:
参与Header处置方法
将token等消息放入Feign恳求头中,关键经过重写RequestInterceptor的apply方法成功
定义config
@ConfigurationpublicclassFeignConfigimplementsRequestInterceptor{@Overridepublicvoidapply(RequestTemplaterequestTemplate){//参与tokenrequestTemplate.header("token","eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ");}}
定义service
@Service@FeignClient(url="${outSide.url}",name="feignServer",configuration=FeignDemoConfig.class)publicinterfaceTokenDemoClient{@RequestMapping(value="/custom/outSideAddToken",method=RequestMethod.POST)@ResponseBodypublicStringgetMessage(@Valid@RequestBodyTestDtotestDto);}
定义controller
//测试feign调用外部接口入口,加上token@PostMapping("/testToken")publicStringtest4(@RequestBodyTestDtotestDto){returntokenDemoClient.getMessage(testDto);}
SpringCloud系列-2Ribbon简介与应用
负载均衡:建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
负载均衡说白了其实就是伴随着微服务架构的诞生的产物;过去的单体架构,前端页面发起请求,然后后台接收请求直接处理,这个时候不存在什么负载均衡;但是随着单体架构向微服务架构的演变,每个后台服务可能会部署在多台服务器上面,这个时候页面请求进来,到底该由哪台服务器进行处理呢?所以得有一个选择,而这个过程就是负载均衡;同时选择的方案有很多种,例如随机挑选一台或者一台一台轮着来,这就是负载均衡算法。
也可以通过例子来帮助自己记忆,就好比古代皇帝翻牌子,最开始皇帝只有一个妃子,那不存在翻牌子这回事,再怎么翻也只能是这一个妃子侍寝。但是随着妃子多了,就得有选择了,不能同时让所有妃子一起侍寝。
工作原理图如下:
HTTP重定向服务器是一台普通的应用服务器,其唯一个功能就是根据用户的HTTP请求计算出一台真实的服务器地址,并将该服务器地址写入HTTP重定向响应中返回给用户浏览器。用户浏览器在获取到响应之后,根据返回的信息,重新发送一个请求到真实的服务器上。DNS服务器解析到IP地址为192.168.8.74,即HTTP重定向服务器的IP地址。重定向服务器计根据某种负载均衡算法算出真实的服务器地址为192.168.8.77并返回给用户浏览器,用户浏览器得到返回后重新对192.168.8.77发起了请求,最后完成访问。
这种负载均衡方案的优点是比较简单,缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;同时,重定向服务器本身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;因此实践中很少使用这种负载均衡方案来部署。
DNS(Domain Name System)是因特网的一项服务,它作为域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网。人们在通过浏览器访问网站时只需要记住网站的域名即可,而不需要记住那些不太容易理解的IP地址。在DNS系统中有一个比较重要的的资源类型叫做主机记录也称为A记录,A记录是用于名称解析的重要记录,它将特定的主机名映射到对应主机的IP地址上。如果你有一个自己的域名,那么要想别人能访问到你的网站,你需要到特定的DNS解析服务商的服务器上填写A记录,过一段时间后,别人就能通过你的域名访问你的网站了。DNS除了能解析域名之外还具有负载均衡的功能,下面是利用DNS工作原理处理负载均衡的工作原理图:
由上图可以看出,在DNS服务器中应该配置了多个A记录,如 IN A 192.168.8.75; IN A 192.168.8.76; IN A 192.168.8.77;
因此,每次域名解析请求都会根据对应的负载均衡算法计算出一个不同的IP地址并返回,这样A记录中配置多个服务器就可以构成一个集群,并可以实现负载均衡。上图中,用户请求,DNS根据A记录和负载均衡算法计算得到一个IP地址192.168.8.77,并返回给浏览器,浏览器根据该IP地址,访问真实的物理服务器192.168.8.77。所有这些操作对用户来说都是透明的,用户可能只知道这个域名。
DNS域名解析负载均衡有如下优点:
同时,DNS域名解析也存在如下缺点:
请求过程:
用户发来的请求都首先要经过反向代理服务器,服务器根据用户的请求要么直接将结果返回给用户,要么将请求交给后端服务器处理,再返回给用户。
反向代理负载均衡
优点:
缺点:
代码实现
由于不同的服务器配置不同,因此它们处理请求的能力也不同,给配置高的服务器配置相对较高的权重,让其处理更多的请求,给配置较低的机器配置较低的权重减轻期负载压力。加权轮询可以较好地解决这个问题。
1.思路
根据权重的大小让其获得相应被轮询到的机会。
可以根据权重我们在内存中创建一个这样的数组{s1,s2,s2,s3,s3,s3},然后再按照轮询的方式选择相应的服务器。
2.缺点:请求被分配到三台服务器上机会不够平滑。前3次请求都不会落在server3上。
Nginx实现了一种平滑的加权轮询算法,可以将请求平滑(均匀)的分配到各个节点上。
代码实现
代码实现
思路:这里我们是利用区间的思想,通过一个小于在此区间范围内的一个随机数,选中对应的区间(服务器),区间越大被选中的概率就越大。
已知:
s1:[0,1] s2:(1,3] s3 (3,6]
代码实现
代码实现
REST(Representational State Transfer)表象化状态转变(表述性状态转变),基于HTTP、URI、XML、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是Web服务的一种新的架构风格(一种思想)。
符合上述REST原则的架构方式称为RESTful
在Restful之前的操作:GET 根据用户id查询用户数据POST 新增用户POST 修改用户信息GET/POST 删除用户信息
RESTful用法:GET 根据用户id查询用户数据POST 新增用户PUT 修改用户信息DELETE 删除用户信息
之前的操作是没有问题的,大神认为是有问题的,有什么问题呢?你每次请求的接口或者地址,都在做描述,例如查询的时候用了query,新增的时候用了save,其实完全没有这个必要,我使用了get请求,就是查询.使用post请求,就是新增的请求,我的意图很明显,完全没有必要做描述,这就是为什么有了restful.
幂等性:对同一REST接口的多次访问,得到的资源状态是相同的。
安全性:对该REST接口访问,不会使用服务器端资源的状态发生改变。
SpringMVC原生态的支持了REST风格的架构设计
所涉及到的注解:
---@RequestMapping---@PathVariable---@ResponseBody
传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient。不过此种方法使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。
定义一个简单的restful接口
使用RestTemplate访问该服务
从这个例子可以看出,使用restTemplate访问restful接口非常的 简单粗暴无脑 。(url, requestMap, )这三个参数分别代表 请求地址、请求参数、HTTP响应转换被转换成的对象类型。
RestTemplate方法的名称遵循命名约定,第一部分指出正在调用什么HTTP方法,第二部分指示返回的内容。本例中调用了方法,post指调用了HTTP的post方法,Object指将HTTP响应转换为您选择的 对象类型 。
RestTemplate定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。
实际上,由于Post 操作的非幂等性,它几乎可以代替其他的CRUD操作.
目前主流的负载方案分为以下两种:
Ribbon 是一个基于 HTTP和TCP的客户端负载均衡工具。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。
Spring Cloud Ribbon 虽然只是一个工具类框架,它不像服务注册中心、配置中心、API 网关那样需要独立部署,但是它几乎存在于每一个 Spring Cloud 构建的微服务和基础设施中。因为微服务间的调用,API 网关的请求转发等内容,实际上都是通过 Ribbon 来实现的()。
Ribbon主要提供:
Ribbon模块介绍:
与Nginx的对比
应用场景的区别:
1.先创建两个服务,用于负载均衡
Server 1 和Server2 的端口号要不同,不然起不来
Server 1接口如下:
Server 2接口如下:
启动类都是一样的,如下:
2.创建一个调用方来请求这个接口
引依赖包
配置启动类,并注入 RestTemplate
配置一下 ,如下:
3.验证
再创建一个 测试方法来验证是否生效,放在test 目录下面,代码如下:
先启动 两个server ,然后在 测试 测试类 ,结果如下:
从结果可以看出实现了负载均衡,默认是 轮询策略,Client1和 clien2 依次调用。
Ribbon 中有两种和时间相关的设置,分别是请求连接的超时时间和请求处理的超时时间,设置规则如下:
Ribbon可以通过下面的配置项,来限制httpclient连接池的最大连接数量、以及针对不同host的最大连接数量。
负载均衡的核心,是通过负载均衡算法来实现对目标服务请求的分发。Ribbion中默认提供了7种负载均衡算法:
验证方法:
1.在()方法中加断点
2.在()方法增加断点,观察请求是否进入。
自定义负载均衡的实现主要分几个步骤:
ILoadBalancer 接口实现类做了以下的一些事情:
修改文件
在ribbon负载均衡器中,提供了ping机制,每隔一段时间,就会去ping服务器,由 接口去实现。
单独使用ribbon,不会激活ping机制,默认采用DummyPing(在RibbonClientConfiguration中实例化),isAlive()方法直接返回true。
ribbon和eureka集成,默认采用NIWSDiscoveryPing(在EurekaRibbonClientConfiguration中实例化的),只有服务器列表的实例状态为up的时候才会为Alive。
IPing中默认内置了一些实现方法如下。
在网络通信中,有可能会存在由网络问题或者目标服务异常导致通信失败,这种情况下我们一般会做容错设计,也就是再次发起请求进行重试。
Ribbon提供了一种重试的负载策略:RetryRule,可以通过下面这个配置项来实现
由于在单独使用Ribbon的机制下,并没有开启Ping机制,所以所有服务默认是认为正常的,则这里并不会发起重试。如果需要展示重试机制,需要增加PING的判断。
1.引入依赖包
2.创建一个心跳检查的类
3.修改mall-portal中文件,添加自定义心跳检查实现,以及心跳检查间隔时间。
4.在goods-service这个模块中,增加一个心跳检查的接口
5.测试服务启动+停止,对于请求的影响变化。
LoadBalancer 是Spring Cloud自研的组件,支持WebFlux。
由于Ribbon停止更新进入维护状态,所以Spring Cloud不得不研发一套新的Loadbalancer机制进行替代。
1.引入Loadbalancer相关jar包
2.定义一个配置类,这个配置类通过硬编码的方式写死了goods-service这个服务的实例列表,代码如下
3.创建一个配置类,注入一个LoadBalancerClient
4.修改测试类
5.为了更好的看到效果,修改goods-service模块,打印每个服务的端口号码。
如何使用RestTemplate访问restful服务
Spring MVC本身对Restful支持非常好。 它的@RequestMapping、@RequestParam、@PathVariable、@ResponseBody注解很好的支持了REST。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。