spring boot 改造微服務 可以使用 spring cloud 組件快速實現
Spring Cloud集成相關優質項目推薦(圖片源自springcloud中文網)
首先來集成 eureka 服務註冊與發現
PS:項目是gradle 構建的
新建eurka服務端項目 啓動項加入@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
配置如下
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-server', version: '2.2.3.RELEASE'
server: port: 8761 eureka: client: service-url: defaultZone: http://user:xxxx@localhost:8762/eureka register-with-eureka: false server: enable-self-preservation: false # 設爲false,關閉自我保護 eviction-interval-timer-in-ms: 5000 # 清理間隔 spring: application: name: eureka-1 security: user: name: user password: xxxx
安全起見推薦使用webSecurity 簡單的加密 ,高可用就啓動多個eurekaServer
然後就是eureka客戶端 啓動類加@EnableDiscoveryClient註解 然後配置文件加入(注意要寫spring.application.name 服務的名字)
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: '2.2.3.RELEASE' compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.2.3.RELEASE'
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
然後啓動 會提示
修改下配置 JAR manifest即可
接着啓動客戶端 再去eureka註冊中心查看服務註冊情況
至此 eureka的服務註冊就配置完成了 然後開始配置feign的服務間調用
使用@EnableFeignClients註解 開啓feign的客戶端
然後我喜歡單獨建個package 寫調用另外一個服務的客戶端
@FeignClient(name = "park-info", fallback = ParkInfoClient.ProductClientFallback.class) public interface ParkInfoClient { @PostMapping(value = "/admin/internalCar/isInternalCar", headers = {"version=2.0", "Authorization=xxxx"}) ResultVO isInternalCar(@RequestBody InternalCarRequest params); @PostMapping(value = "/admin/limitCar/isLimitCar", headers = {"version=2.0", "Authorization=xxx"}) ResultVO isLimitCar(@RequestBody InternalCarRequest params); @Component class ProductClientFallback implements ParkInfoClient { @Override public ResultVO isInternalCar(InternalCarRequest params) { return ResultVoUtil.failed("請求失敗"); } @Override public ResultVO isLimitCar(InternalCarRequest params) { return ResultVoUtil.failed("請求失敗"); } } }
然後其他地方直接注入這個Client,調用Client的方法即可調用其他服務, 有複雜對象 新建DTO作爲傳輸對象
配置feign的連接超時、響應超時設置
feign: client: config: default: connectTimeout: 3000 readTimeout: 3000
feign調用也實現了,多個相同的服務負載均衡默認是輪詢方式調用
下面是feign的json轉換使用fastjson
package com.easyparking.cloudplatform.common.webmvc.config; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import java.util.ArrayList; import java.util.List; /** * @author cctv * @date 2020/7/3 14:17 */ @Configuration public class FeignConfig { @Bean public ResponseEntityDecoder feignDecoder() { HttpMessageConverter fastJsonConverter = createFastJsonConverter(); ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter); return new ResponseEntityDecoder(new SpringDecoder(objectFactory)); } @Bean public SpringEncoder feignEncoder(){ HttpMessageConverter fastJsonConverter = createFastJsonConverter(); ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(fastJsonConverter); return new SpringEncoder(objectFactory); } private HttpMessageConverter createFastJsonConverter() { //創建fastJson消息轉換器 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //升級最新版本需加============================================================= List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); supportedMediaTypes.add(MediaType.APPLICATION_PDF); supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.IMAGE_GIF); supportedMediaTypes.add(MediaType.IMAGE_JPEG); supportedMediaTypes.add(MediaType.IMAGE_PNG); supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); supportedMediaTypes.add(MediaType.TEXT_HTML); supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); supportedMediaTypes.add(MediaType.TEXT_PLAIN); supportedMediaTypes.add(MediaType.TEXT_XML); fastConverter.setSupportedMediaTypes(supportedMediaTypes); //創建配置類 FastJsonConfig fastJsonConfig = new FastJsonConfig(); //修改配置返回內容的過濾 //WriteNullListAsEmpty :List字段如果爲null,輸出爲[],而非null //WriteNullStringAsEmpty : 字符類型字段如果爲null,輸出爲"",而非null //DisableCircularReferenceDetect :消除對同一對象循環引用的問題,默認爲false(如果不配置有可能會進入死循環) //WriteNullBooleanAsFalse:Boolean字段如果爲null,輸出爲false,而非null //WriteMapNullValue:是否輸出值爲null的字段,默認爲false fastJsonConfig.setSerializerFeatures( SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue ); fastConverter.setFastJsonConfig(fastJsonConfig); return fastConverter; } }