远程服务调用的几种方式

远程服务调用的方式

 

1.跨域问题:

1.2关于浏览器同源策略的说明

说明:

浏览器规定 当浏览器解析页面时,当遇到ajax请求时 如果请求与当前页面的 协议://域名:端口号都相同时,则满足同源策略 称之为同域请求.浏览器可以正确解析返回值 请求正常. 如果三者中有一项不同,则把请求称之为叫做跨域请求. 浏览器出于安全性的考虑 则不予解析返回值.

在这里插入图片描述

2.解决跨域方法JSONP和跨源资源共享 (CORS)

2.1 JSONP原理说明

1). 利用javaScript标签 动态获取远程数据

<script type="text/javascript" src="http://manage.jt.com/test.json"></script>

2).自定义回调函数

<script type="text/javascript">
        /*JS是解释执行的语言  */
        /*定义回调函数  */
        function hello(data){
            alert(data.name);
        }
    </script>

3). 将返回值结果 进行特殊格式封装

hello({"id":"1","name":"tom"})

 

2.2jQuery中的JSONP

  1. 3编辑页面JS

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP测试</title>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
    $(function(){
        alert("测试访问开始!!!!!")
        $.ajax({
            url:"http://manage.jt.com/web/testJSONP",
            type:"get",             //jsonp只能支持get请求
            dataType:"jsonp",       //dataType表示返回值类型  必须添加
            jsonp: "callback",      //指定参数名称  一般固定写死!!!
            jsonpCallback: "hello",  //指定回调函数名称
            success:function (data){   //data经过jQuery封装返回就是json串
                alert(data.id);
                alert(data.name);
                //转化为字符串使用
                //var obj = eval("("+data+")");
                //alert(obj.name);
            }   
        }); 
    })
</script>
</head>
<body>
    <h1>JSON跨域请求测试</h1>
</body>
</html>

2.3.CORS--跨源资源共享

一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。

2.4.CORS跨域原理

说明: CORS 在响应头中标识哪些网址可以访问服务器.CORS的配置是服务器端的配置和浏览器没关系.

在这里插入图片描述

@CrossOrigin(value = "url...")   //标识当前类或方法中 允许被其他服务器访问
                                            //预检: 在规定时间内同源策略不会再次拦截 提高效率

 

3.HttpClient(远程服务调用,不属于跨域)

简介:

HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

描述:

一般的情况下 采用跨域一般处理一些简单的数据.对于安全性要求不是特别的高. 并且业务相对简单.如果有需求对安全性及业务要求严格,则使用跨域的方式则不能满足用户的需求.则应该采用HttpClient(微服务底层实现)方式实现远程数据访问.

1.导入jar包

        <!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

2.编辑入门案例

@Test
public void testGet() throws IOException {
    //1.实例化对象
    HttpClient httpClient = HttpClients.createDefault();
    //2.定义请求网址
    String url = "http://www.baidu.com";  //html代码
    //3.定义请求方式
    HttpGet get = new HttpGet(url);
  //HttpGet post = new HttpPost(url);
    //4.发送请求
    HttpResponse httpResponse = httpClient.execute(get);
    //5.判断状态码
    int status = httpResponse.getStatusLine().getStatusCode();
    if(status == 200) {
        //6.获取数据
        HttpEntity httpEntity = httpResponse.getEntity();
        String html = EntityUtils.toString(httpEntity, "UTF-8");
        System.out.println(html);
    }
}

 

4.远程调用 - RestTemplate

spring 提供的,专门用来做 Rest API 远程调用的工具

它类似于 HttpClient,是执行http请求的工具,

RestTemplate对RestAPI调用做了高度封装,提供了非常简便的方法:

  • getForObject(url?name={1}&age={2},转换的类型, 提交的参数数据)

  • postForObject(url, 协议体数据, 转换的类型)

 

Springboot项目中:

  1. 在配置类中实例化RestTemplate ,创建对象交给SpringBoot实现控制反转

  2. RibbonController 中,使用 RestTemplate 调用 别的服务器

  3. 使用restTemplate.getForObject()方法

     @GetMapping("/item-service/{orderId}")
        public JsonResult<List<Item>> getItems(@PathVariable String orderId){
            //调用远程02项目,获得商品列表
    ​
            //{1}.{2}...  是RestTemplate 提供的占位符格式
    ​
            //RestTemplate 必须给出具体的服务器地址url
    ​
            return restTemplate.getForObject("http://localhost:80/{1}",  //给出了具体url 满足不了负载均衡
                                    JsonResult.class,       //返回值类型.class
                                    orderId);               //传入的参数
            //restTemplate.postForObject("http://item-servic/decreaseNumber}", items, JsonResult.class);

     

5.Ribbon

对 RestTemplate 的功能进行了增强,添加了负载均衡重试的功能

 

负载均衡:

  1. 服务器有集群时会自动实现负载均衡

    1. 对 RestTemplate 添加@LoadBalanced 注解,对它进行增强

          @Bean
          @LoadBalanced
          public RestTemplate restTemplate(){
              return new RestTemplate();
          }
    2. 调用地址,改成服务id

            //Ribbon 利用AOP 对RestTemplate 进行了增强,提供服务器负载均衡的功能
            //Ribbon根据注册表注册的主机地址列表,做负载均很
            return rt.getForObject("http://item-service/{1}",   //hostname可以在注册中心查找对应服务器,实现负载均衡
                                    JsonResult.class,           //返回值类型.class
                                    orderId);                   //传入的参数

     

重试:

  1. 添加 spring-retry 依赖

            <!--Ribbon重试依赖 -->
            <dependency>
                <groupId>org.springframework.retry</groupId>
                <artifactId>spring-retry</artifactId>
            </dependency>

     

  2. 配置重试参数

    • ribbon.MaxAutoRetries - 单台服务器重试次数

    • ribbon.MaxAutoRetriesNextServer - 更换服务器的次数

    • ribbon.OkToRetryOnAllOperations - 是否对所有类型请求进行重试,默认只对GET重试

    • @Bean
          @LoadBalanced
          public RestTemplate restTemplate(){
              SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
              factory.setReadTimeout(1000);
              /*factory.setConnectTimeout(1000);*/
              return new RestTemplate(factory);
          }

       

    • ConnectTimeout - 连接超时时间

    • ReadTimeout - 已建立连接,并且已发送请求,接收响应的超时时间

    • 两个超时时间设置,不能在yml中设置,只能使用java代码设置

      ribbon:
        MaxAutoRetries: 1             #表示尝试重试最大的连接次数
        MaxAutoRetriesNextServer: 2   #表示重试最多跳转的服务器数
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值