1. 程式人生 > >Springcloud微服務之間呼叫

Springcloud微服務之間呼叫

【方法1】Springcloud之間的呼叫

1、符合該架構規範的@FeignClient訪問方式,feign在Springcloud中的使用。

(1)新增feign依賴

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

(2)建立feignClient    

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

//@FeignClient(value = "offerprpall")
@FeignClient(name = "offerprpall",url = "http://10.75.5.10:19225/")
@Service
public interface LoginIntializtionFeign {
    /**
     *  @description: 初始介面開關載入
     *  @param:InitializationQueryVo  入參
     *  @return InitializationResponseVo 返參
     */
    @RequestMapping(value = "/comCode/comCodeApi",method = {RequestMethod.POST})
    public InitializationResponseVo loginIntializtion(@RequestBody InitializationQueryVo queryVo) throws Exception;//複合型別好像預設是POST請求
  @RequestMapping( value = "/findAll/{name}",method = RequestMethod.GET)
  public List<SpringUser> findAll(@PathVariable("name") String name);//get方式

@FeignClient(value = "offerprpall")這種方式是常見的寫法, 用於通知Feign元件對該介面進行代理(不需要編寫介面實現),name屬性指定我們要呼叫哪個服務,不帶URl的是在註冊中心已經配置好。使用者可直接通過@Autowired注入。如下

@Autowired
private LoginIntializtionFeign loginIntializtionFeign;
  • @RequestMapping表示在呼叫該方法時需要向/findAll/{name}傳送GET請求。

原理:Spring Cloud應用在啟動時,Feign會掃描標有@FeignClient註解的介面,生成代理,並註冊到Spring容器中。生成代理時Feign會為每個介面方法建立一個RequetTemplate物件,該物件封裝了HTTP請求需要的全部資訊,請求引數名、請求方

法等資訊都是在這個過程中確定的,Feign的模板化就體現在這裡。

(3)啟動類上添加註解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.ace.cache.EnableAceCache;

@EnableEurekaClient
@SpringBootApplication
@ComponentScan(basePackages={"com.guorenpcic.grecar","com.gr.framework.security.common"})
// 開啟druid監控
@ServletComponentScan("com.guorenpcic.grecar.config.druid")
// 開啟事務
@EnableTransactionManagement
// 開啟熔斷監控
@EnableCircuitBreaker
//// 開啟服務鑑權
@EnableFeignClients({"com.gr.framework.security.auth.client.feign","com.guorenpcic.grecar.feign"})
@EnableAceCache 
public class GrECarApplication {
    public static void main(String[] args) {
        SpringApplication.run(GrECarApplication.class, args);
    }
}

(4)配置檔案

logging:
    level:
         com:guorenpcic.grecar: INFO
         com.guorenpcic.grecar.mapper: DEBUG
         test: INFO

spring:
    application:
        name: gr-ecar-app
    jackson:
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
        default-property-inclusion: non_empty
    datasource:
        name: test
        #測試環境
        url: jdbc:mysql://xxxxxx:3306/gr_ecar?useUnicode=true&characterEncoding=UTF8
        username: xxx
        password: xxx
        # 使用druid資料來源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20
    rabbitmq:
        host: xx.xx.xx.xx
        port: xxx
        username: xxxx
        password: password

# 配置資料庫
mybatis:
    basepackage: com.guorenpcic.grecar.mapper
    xmlLocation: classpath:mapper/**/*.xml


server:
    port: 21113

# 配置spring cloud 服務發現
eureka:

    instance:
        statusPageUrlPath: /info
        healthCheckUrlPath: /health
        # docker 部署開啟
        prefer-ip-address: true
        ip-address: 10.75.5.10
    client:
        serviceUrl:
#            defaultZone: http://xxxxxxxx:xxxx/eureka/
            defaultZone: http://xxxxxxxx:8761/eureka/
            #開發環境
#          defaultZone: http://xx.xx.xx.xx:${EUREKA_PORT:8001}/eureka/


# 配置swagger
swagger:
    basepackage: com.guorenpcic.grecar.security.common.rest
    service:
        name: 車險出單平臺後端應用
        description: 車險出單平臺後端應用服務介面文件
        developer: dc
#redis-cache 相關
redis:
    pool:
         maxActive: 300
         maxIdle: 100
         maxWait: 1000
    host: xxxxxxxxx
    port: xxxx
    password:
    timeout: 2000
    # 服務或應用名
    sysName: gr-ecar
    enable: true
    database: 0
# 配置使用者認證和服務認證資訊
auth:
  serviceId: gr-auth
  user:
    token-header: Authorization
  client:
    id: gr-ecar-app
    secret: 9zRzsRos
    token-header: client-token
hystrix:
    command:
        default:
            execution:
                timeout:
                    enabled: false
ribbon:
    ReadTimeout: 120000
    ribbon:
        ConnectTimeout: 30000

【方法2】

2、微服務之間的呼叫,不用feignClient,直接用http想呼叫其他專案的介面(不是微服務之間也能呼叫,如Springcloud調servlet方法)

  public static String validateIdentity(String url, String jsonString) throws Exception {
        SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault());
        CloseableHttpClient httpClient = HttpClients.custom().setRoutePlanner(routePlanner).build();
        // DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(jsonString,"gbk");// 解決中文亂碼問題
        entity.setContentEncoding("gbk");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        System.out.println(jsonString);
        HttpResponse httpResponse = httpClient.execute(httpPost);
       
        String resultJson = EntityUtils.toString(httpResponse.getEntity());
        resultJson = URLDecoder.decode(resultJson, "UTF-8");
        System.out.println(resultJson);
        return resultJson;
    }
String responseJson = HttpUtil.validateIdentity(BASE_URL+"comCode/comCodeApi",JSON.toJSONString(initializationQueryVo));
            initializationResponseVo = JSON.parseObject(responseJson, InitializationResponseVo.class);

擴充套件呼叫:

private List<PrpDunitMaintenanceSHDto>  queryPrpDunitMaintenanceSH(SelectTagListDto selectTagListDto) throws Exception {
           String url  = GR_DMS_URL+"/prpDunitMaintenanceSH/queryPrpDunitMaintenanceSH";//另一個系統的url
           LOGGER.info("‘’‘’‘’‘’‘’‘’‘’‘’‘’決策單元地址:"+ url);//測試所用
           String res = HttpClientUtil.validateIdentity(url, JSONObject.toJSONString(selectTagListDto),"UTF-8");//http方式呼叫,在調介面成功後一直不識別中文,注意要加上入參的編碼格式
           LOGGER.info("‘’‘’‘’‘’‘’‘’‘’‘’‘’決策單元結果:"+res );//測試所用
           List<PrpDunitMaintenanceSHDto> prpdunitMaintenanceSHDtoList = JSONObject.parseArray(res,PrpDunitMaintenanceSHDto.class);
           return prpdunitMaintenanceSHDtoList;
     }
public static String validateIdentity(String url, String jsonString,String bianma) throws Exception {
        SystemDefaultRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault());
        CloseableHttpClient httpClient = HttpClients.custom().setRoutePlanner(routePlanner).build();
        //設定超時時間 by chenxiaohui 20180721 beign
        //RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();//設定請求和傳輸超時時間
        //設定超時時間 by chenxiaohui 20180721 end
        // DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(jsonString,bianma);// 解決中文亂碼問題
        entity.setContentEncoding("gbk");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        /** 設定超時時間 by chenxiaohui 20180721 beign  */
        //httpPost.setConfig(requestConfig);
        /** 設定超時時間 by chenxiaohui 20180721 end  */
        System.out.println(jsonString);
        HttpResponse httpResponse = httpClient.execute(httpPost);
        String resultJson = EntityUtils.toString(httpResponse.getEntity());
        resultJson = URLDecoder.decode(resultJson, "UTF-8");//反參的編碼格式
        System.out.println("======================"+resultJson);//獲得核心的計算保費反參
        return resultJson;
    }