Spring Cloud 是spring團隊推出的基於SpringBoot的分佈式微服務框架,爲開發者提供了在分佈式系統(如配置管理、服務發現、斷路器、智能路由、微代理、控制總線、一次性 Token、全局鎖、決策競選、分佈式會話和集羣狀態)操做的開發工具。java
隨着部門內的產品,包括對外提供的一些服務愈來愈多,另外有一些基礎的功能須要抽象出來,團隊內部就開始對一些接口和業務進行服務化的改造,通過一些對比,初步採用的方案就是spring cloud。現對spring cloud的使用作一些簡單的總結。nginx
項目自己都是基於maven的,首先能夠利用maven的parent project的特性來管理spring cloud依賴的版本,spring cloud自己也提供了幾個starter project的maven依賴管理的基礎jar包。大體的配置以下:程序員
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> </exclusions> </dependency> ... </dependencies>複製代碼
dubbo的服務的註冊和發現能夠依賴於zk或者redis來實現,spring cloud官方提供了本身的解決方案,使用eureka來作的,因此咱們須要一個eureka server,實現起來很簡單,按照示例來便可:web
pom中添加redis
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>複製代碼
主程序以下spring
@SpringBootApplication@EnableEurekaClientpublic class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class, args); } }複製代碼
在application.properties中添加監聽的端口號,如server.port=8761,而後啓動程序便可跨域
在main函數所在程序中添加 @SpringBootApplication註解tomcat
在application.properties中添加上面註冊中心的地址,好比說, eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/ 注意,生產環境這個註冊中心是須要多節點的安全
設置服務註冊的名稱,以及監聽的端口,也是在application.properties中的,如:性能優化
spring.application.name=spam-detect-service server.port=8082複製代碼
在controller上添加 @RestController及方法的@RequestMapping註解
啓動main函數,咱們的服務就啓動並註冊到eureka server上了
在主程序的入口添加註解
@SpringBootApplication@EnableEurekaClient複製代碼
添加一個RestTemplate實例(在主程序中添加便可),聲明爲bean,方便別的服務進行autowired注入,用來進行HTTP調用
@LoadBalanced@BeanRestTemplate restTemplate() { return new RestTemplate(); }複製代碼
配置application.properties,主要是配置註冊中心的地址 eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/
在程序的代碼中使用restTemplate根據服務名稱訪問服務
@AutowiredRestTemplate restTemplate;static final String SERVICE_NAME = "spam-detect-service";public MMResult spamDetect(String type, String image) { try { .... MMResult r = restTemplate.postForObject("http://" + SERVICE_NAME + "/xxxx", request, MMResult.class); return r; } catch (Throwable t) { .... } }複製代碼
Spring Cloud的一個重要貢獻者是Netflix,它提供了構建一個分佈式rpc系統的關鍵的一些核心模塊,在spring cloud 中,咱們能夠經過幾個簡單的註釋,就能構造一個分佈式系統。系統中提供的模式包括服務發現(Eureka),斷路器(Hystrix),智能路由(Zuul)和客戶端負載平衡等。
Spring Cloud默認使用netflix貢獻的eureka來做爲服務註冊和發現的。 服務發現默認採用EurekaClient,使用方式是:
@Autowiredprivate EurekaClient discoveryClient;複製代碼
多是以爲EurekaClient不太好用,spring同時提供了替代的方式,就是基於Feign和上面提到的RestTemplate,在實例上添加@RestTemplate註解便可。
在應用程序的main函數上添加以下註解便可
@SpringBootApplication@EnableEurekaServer複製代碼
Spring Cloud採用ribbon來實現負載均衡loadbalance,使用restTemplate的時候添加@LoadBalance註解便可。服務的失敗重試retry、超時配置等,能夠在application.properties中作一下配置便可
ribbon.ConnectTimeout=500ribbon.ReadTimeout=5000ribbon.MaxAutoRetries=1ribbon.MaxAutoRetriesNextServer=1ribbon.OkToRetryOnAllOperations=true複製代碼
ribbon還能夠不使用服務名稱的方式進行調用,能夠把服務配置爲固定的物理地址列表進行訪問,爲服務名稱
.ribbon.listOfServers= 127.0.0.1:1234,127.0.0.1:1235
當服務不可用的時候,或者須要進行併發訪問控制的時候使用的,spring cloud採用Hystrix來實現,在業務方法上加上@HystrixCommand 註解
配置@HystrixCommand的fallback屬性,如@HystrixCommand(fallbackMethod = "systemError"),注意systemError方法須要與業務方法的參數是一致的
配置@HystrixCommand的properties屬性
commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000") }, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "5"), @HystrixProperty(name = "maxQueueSize", value = "10") }複製代碼
zuul是基於jvm的路由轉發和負載均衡,有點相似於nginx,可是是基於jvm的,咱們java程序員能夠很方便的在上面作一些事情,它一般是放在入口,能夠作一些轉發、安全校驗等統一的事情。它既能夠轉發到本地的服務,也能夠轉發到互聯網上其它url(使用ribbon的固定物理地址方式)。
在application.properties中配置
zuul.routes.<users>.path = /myusers/** zuul.routes.<users>.serviceId = users複製代碼
@Beanpublic PatternServiceRouteMapper serviceRouteMapper() { return new PatternServiceRouteMapper( "(?<name>^.+)-(?<version>v.+$)", "${version}/${name}"); }複製代碼
能夠配置zuul.host.maxTotalConnections 和 zuul.host.maxPerRouteConnections 能夠控制路由的併發量
SpringCloud註冊服務的時候使用的是InetUtils的findFirstNonLoopbackAddress()方法,有時候咱們的服務器被發現的地址,恰恰不是機房內的互通ip,致使服務註冊上了,調用的時候訪問不通,這時候咱們就須要設置忽略這個ip了,在配置文件中 spring.cloud.inetutils.ignoredInterfaces=eth0
不討論跨域的必要性,若是須要用到跨域請求,須要作如下配置
在代碼中設置 response.addHeader("Access-Control-Allow-Origin", "*");
添加option處理類
@RestControllerpublic class OptionBean { @RequestMapping(method = RequestMethod.OPTIONS, value = "/**") public ResponseEntity manageOptions(HttpServletResponse response) { response.addHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS"); return new ResponseEntity(HttpStatus.OK); } }複製代碼
3.設置 spring.mvc.dispatch-options-request=true
如須要設置post size,upload file dize 等
在此我向你們推薦一個架構學習交流羣。交流學習羣號:821169538 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多。
@Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize("20MB"); factory.setMaxRequestSize("20MB"); return factory.createMultipartConfig(); } @Bean public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory(); tomcatFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() { @Override public void customize(Connector connector) { // tomcat default nio connector Http11NioProtocol handler = (Http11NioProtocol) connector .getProtocolHandler(); // acceptCount is backlog, default value is 100, you can change // which you want value in here handler.setBacklog(100); handler.setMaxThreads(1000); connector.setMaxPostSize(-1); } }); return tomcatFactory; }複製代碼
eureka.client.healthcheck.enabled=true
本文來自網易雲社區 ,經做者王洪偉受權發佈。