將總體功能按着模塊劃分紅多個獨立的單元,這些單元能夠獨立部署,它們以前經過輕量級的web api方式進行通信,對於微服務框架來講,最流行的就是springcloud和Service Fabric,前者是java開發,後者是.net的產品,今天主要介紹一下springcloud!java
參考文章:https://dzone.com/articles/microservice-architecture-with-spring-cloud-and-doweb
功能即服務-Functional Servicesspring
每一個功能爲一個服務,能夠獨立部署api
METHOD | PATH | DESCRIPTION |
---|---|---|
GET | /accounts/{account} | Get specified account data |
GET | /accounts/current | Get current account data |
GET | /accounts/demo | Get demo account data (pre-filled incomes/expenses items, etc) |
PUT | /accounts/current | Save current account data |
POST | /accounts/ | Register new account |
配置中心-Config Server安全
全部項目的配置信息都存儲在遠程,啓動後同步到本地,有過時機制app
spring: application: name: notification-service cloud: config: uri: http://config:8888 fail-fast: true
服務註冊和發現-Eureka框架
每一個服務在啓動後都被註冊到eureka裏,其它服務從eureka裏經過服務名拿到服務的地址,進行調用異步
spring:
application:
name: notification-service
熔斷器和監視器- Hystrix Dashboard微服務
當服務進行相互調用後,它多是多層次的調用,當某一層出現問題後,它下面的服務就不須要等待超時了,直接返回失敗,這就是熔斷器;而每一個服務運行的狀態可使用監視器查看到。測試
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableHystrixDashboard @EnableCircuitBreaker public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
解耦和異步通和的消息隊列
隊列服務用了比較流行的rabbitmq,比起kafka來講,它不只更輕,並且更安全,有本身的ack機制!
Api網關
請求走統一的入口,而後根據配置去反向代理,通常地會在當前入口後加一個二級路徑便可,在客戶端看來他就好像是一個系統!
zuul: routes: notification-service: path: /notifications/** serviceId: notification-service stripPrefix: false
統一受權服務
全部接口均可以被受權註解統一攔截,進行受權,通常採用oauth2的協議!
@PreAuthorize("#oauth2.hasScope('server')") @RequestMapping(value = "accounts/{name}", method = RequestMethod.GET) public List<DataPoint> getStatisticsByAccountName(@PathVariable String name) { return statisticsService.findByAccountName(name); }
Feign代替傳統的Http
Feign是經過定義本地接口來模擬對遠程接口的調用的,在生產環境中它會使用服務名+Feign接口路徑來實現對遠程資源的調用,而在測試環境裏,他又會根據你mock的接口進行調用,這對於TDD開發是很是必要的,你在測試時不須要依賴外部資源!
@FeignClient(name = "statistics-service") public interface StatisticsServiceClient { @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) void updateStatistics(@PathVariable("accountName") String accountName, Account account); }
感謝各位的閱讀!