If you have a friend who has dubbo/dubbox experience, see this diagram below, it must be familiar, is the most basic way of SOA architecture.
In contrast to Dubbo, the 3 major elements of spring cloud are implemented with the following components:
1. Registration Center:
Spring Cloud uses Eureka server by default for the registry, and Dubbo uses zookeeper by default. Eureka's registration information is stored in a double-decker map object, in other words, in memory, unlike zookeeper, which is persisted in the node for a long time.
2. Service provider:
Spring-web (Spring MVC) provides a comprehensive HTTP rest service framework that can provide rest services with this set. (The currently available samples from Spring cloud are basically HTTP rest services, which in theory should also be extended to RPC services, while Dubbo is RPC-based, some differences)
3. Service Consumer:
Depending on the spring-web, load balancing is done using ribbon components, with the general principle of discovering available services from the registry, caching them locally, and then invoking a certain load-balancing algorithm. (similar to Dubbo, except that Dubbo is a load balancer of its own)
The following are the most basic examples of these three parties:
I. Structure of the project
Note:Spring-cloud is based entirely on spring boot to build the project, so unfamiliar with spring boot, it is recommended to look at this blog's Spring Boot series first.
Register-center-Eureka Registration Center
SERVICE-API for service Contracts
Service-consumer for service consumers
Service-provider as a service provider
Second,Register-center
2.1 Dependencies
Buildscript { repositories { maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } } dependencies { classpath ("Org.springframework.boot:spring-boot-gradle-plugin:1.5.4.release") }}apply Plugin: ' Spring-boot ' dependencymanagement { Imports { Mavenbom ' Org.springframework.cloud: Spring-cloud-dependencies:dalston. RELEASE " }}dependencies { compile ' org.springframework.cloud:spring-cloud-starter-eureka-server ' Compile ' org.springframework.boot:spring-boot-starter-actuator ' testcompile ' org.springframework.boot: Spring-boot-starter-test '}
2.2 Main entry procedure
Package Com.cnblogs.yjmyzz.spring.cloud.study;import Org.springframework.boot.springapplication;import Org.springframework.boot.autoconfigure.springbootapplication;import org.springframework.cloud.netflix.eureka.server.enableeurekaserver;/** * Created by the Bodhi tree under the Poplar on 2017/6/17. */@SpringBootApplication @enableeurekaserverpublic class RegisterServer {public static void Main (string[] args) { C1/>springapplication.run (Registerserver.class, args);} }
Mainly by the top of the @enableeurekaserver this annotation, the other completely no flower head.
2.3 Configuration
Server: Port:8000eureka: client: register-with-eureka:false fetch-registry:false Service-url: Defaultzone:http://localhost:8000/eureka
Explain:
The registry itself is also a service and can be registered as a normal service to other registries, because in this example, only one Eureka server itself acts as a registry and does not need to synchronize registration information with other registries, so it is set to false. The last line of the Defaultzone, first contact can be first, the first understanding of the Registration center external exposure address can be.
2.4 Start
After booting, browse http://localhost:8000/and you can see something like:
Now there is no service registration, so in application, show no instances available.
Third,Service-api
To facilitate the following, define a service interface and the corresponding DTO
Package Com.cnblogs.yjmyzz.spring.cloud.study.api;import com.cnblogs.yjmyzz.spring.cloud.study.dto.userdto;/** * Created by Poplar under the Banyan tree on 2017/6/17. */public interface UserService { userdto finduser (Integer userId);}
And
Package Com.cnblogs.yjmyzz.spring.cloud.study.dto;import Lombok. data;/** * Created by the Bodhi tree under the Poplar on 2017/6/17. */@Datapublic class Userdto { private Integer userId; Private String UserName;}
Iv.Service-provider
4.1 Dependencies
Buildscript { repositories { maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } } dependencies { classpath ("Org.springframework.boot:spring-boot-gradle-plugin:1.5.4.release") }}apply Plugin: ' Spring-boot ' dependencymanagement { Imports { Mavenbom ' Org.springframework.cloud: Spring-cloud-dependencies:dalston. RELEASE " }}dependencies { compile (Project (": Service-api ")) compile ' Org.springframework.cloud: Spring-cloud-starter-eureka ' compile ' org.springframework.boot:spring-boot-starter-actuator ' compile ' Org.springframework.boot:spring-boot-starter-web ' testcompile ' org.springframework.boot: Spring-boot-starter-test '}
4.2 Interface implementation
Package Com.cnblogs.yjmyzz.spring.cloud.study.service.impl;import Com.cnblogs.yjmyzz.spring.cloud.study.api.userservice;import Com.cnblogs.yjmyzz.spring.cloud.study.dto.UserDTO; Import Org.springframework.stereotype.Service; @Service ("UserService") public class Userserviceimpl implements UserService { @Override public userdto finduser (Integer userId) { userdto user = new Userdto (); User.setuserid (userId); User.setusername ("Yang over under the Bodhi Tree"); return user; }}
Here is just a hint, return a fixed userdto instance directly.
4.3 Controller
Package Com.cnblogs.yjmyzz.spring.cloud.study.controller;import Com.cnblogs.yjmyzz.spring.cloud.study.api.userservice;import Com.cnblogs.yjmyzz.spring.cloud.study.dto.UserDTO; Import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.web.bind.annotation.getmapping;import org.springframework.web.bind.annotation.PathVariable; Import Org.springframework.web.bind.annotation.RestController; @RestControllerpublic class Usercontroller { @ autowired private UserService userservice; @GetMapping ("/user/{id}") Public userdto Finduser (@PathVariable Integer id) { return Userservice.finduser (ID ); }}
Here is a new annotation getmapping, equivalent to the previous Springmvc in @requestmapping (method = Requestmethod.get), more concise.
So far, it is no different from regular SPRINGMVC.
4.4 Main entrance
Package Com.cnblogs.yjmyzz.spring.cloud.study;import Org.springframework.boot.springapplication;import Org.springframework.boot.autoconfigure.springbootapplication;import org.springframework.cloud.client.discovery.enablediscoveryclient;/** * Created by yangjunming on 2017/6/17. */@EnableDiscoveryClient @springbootapplicationpublic class ServiceProvider {public static void Main (string[] args) { springapplication.run (serviceprovider.class, args);} }
Still @EnableDiscoveryClient burden, indicating that this is a Eureka client program (i.e., able to register with Eureka Server)
4.5 Configuration
Server: port:8001spring: application: name: "Service-provider-demo" Eureka: instance: Prefer-ip-address:true Client: service-url: defaultzone:http://localhost:8000/eureka/
It should not be difficult to understand, the last few lines, the expression of their own IP address to http://localhost:8000/eureka/registration
4.6 Start
After the success of the launch, look at Eureka just now the page, you will find that has been registered in.
Note: You can put service-provider more boot several instances (the port staggered, do not conflict), and then observe the interface, you can see the registration of multiple provider instances
Wu,service-consumer
5.1 Dependencies
Buildscript { repositories { maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } } dependencies { classpath ("Org.springframework.boot:spring-boot-gradle-plugin:1.5.4.release") }}apply Plugin: ' Spring-boot ' dependencymanagement { Imports { Mavenbom ' Org.springframework.cloud: Spring-cloud-dependencies:dalston. RELEASE " }}dependencies { compile (Project (": Service-api ")) compile ' Org.springframework.cloud: Spring-cloud-starter-eureka ' compile ' org.springframework.boot:spring-boot-starter-actuator ' compile ' Org.springframework.cloud:spring-cloud-starter-ribbon ' compile ' org.springframework.boot: Spring-boot-starter-web ' testcompile ' org.springframework.boot:spring-boot-starter-test '}
5.2 to build a call controller
Package Com.cnblogs.yjmyzz.spring.cloud.study.service.controller;import Com.cnblogs.yjmyzz.spring.cloud.study.dto.userdto;import org.springframework.beans.factory.annotation.Autowired ; Import Org.springframework.cloud.client.serviceinstance;import Org.springframework.cloud.client.discovery.discoveryclient;import Org.springframework.cloud.client.loadbalancer.loadbalancerclient;import Org.springframework.web.bind.annotation.getmapping;import org.springframework.web.bind.annotation.PathVariable; Import Org.springframework.web.bind.annotation.restcontroller;import Org.springframework.web.client.RestTemplate ; Import java.util.list;/** * Created by yangjunming on 2017/6/17. */@RestControllerpublic class Ordercontroller {@Autowired private resttemplate resttemplate; @Autowired private loadbalancerclient loadbalancerclient; @Autowired private discoveryclient discoveryclient; @GetMapping ("/order/{userid}/{orderno}") Public String FindOrder (@PathVariable Integer userId, @PaThvariable String orderno) {userdto user = resttemplate.getforentity ("http://SERVICE-PROVIDER-DEMO/user/" + userId , Userdto.class). GetBody (); if (user! = null) {return user.getusername () + "order" + OrderNo + "Found! "; } return "user does not exist! "; } @GetMapping ("/user-instance") public list<serviceinstance> Showinfo () {return THIS.DISCOVERYCLIENT.G Etinstances ("Service-provider-demo"); } @GetMapping ("/log-instance") public serviceinstance chooseinstance () {return This.loadBalancerClient.choos E ("Service-provider-demo"); }}
There are 3 URLs exposed, one for each:
A./order/{userid}/{orderno} This is used to sample how to invoke the method in Service-provider, note here we do not use HTTP://LOCALHOST:8001/USER/1 to invoke, and by http:// Service-provider-demo/user/Specifies the application name of the Service-provider, allowing the system to discover the service from the registry.
B./user-instance,/log-instance These two URLs are used to assist in outputting information related to service instances discovered from the registry, not necessarily.
There are also two injected instances: Resttemplate, loadbalancerclient, respectively, to initiate a rest HTTP request, and to use load balancing to pick out an available instance from the list of available services.
5.3 Main entrance
Package Com.cnblogs.yjmyzz.spring.cloud.study.service;import Org.springframework.boot.springapplication;import Org.springframework.boot.autoconfigure.springbootapplication;import Org.springframework.cloud.client.discovery.enablediscoveryclient;import Org.springframework.cloud.client.loadbalancer.loadbalanced;import Org.springframework.context.annotation.Bean; Import org.springframework.web.client.RestTemplate; @EnableDiscoveryClient @springbootapplicationpublic class Serviceconsumer { @Bean @LoadBalanced resttemplate resttemplate () { return new resttemplate (); } public static void Main (string[] args) { springapplication.run (serviceconsumer.class, args);} }
Still rely on two key annotations: @EnableDiscoveryClient,@LoadBalanced, especially @loadbalanced, after this modified resttemplate, is not a common resttemplate, but a load-balancing capability of the resttemplate, that is, each time the load balancing algorithm, from the list of available services, pick one to call.
5.3 Start
Can be seen from the Eukera, Service-provider and Service-consumer are registered in the.
Call to try: http://localhost:8002/order/1/1000, success will see the following output
Note: At this point, you can stop the registry Eureka Server, and then call the next http://localhost:8002/order/1/1000, you will find that can still be called normally, the Registry Service list, in this machine is a cache, this with dubbo/ Dubbox similar.
In addition, you can verify the following load balancing method:
Start the Service-provider 2, open two terminal window:
Java-jar Xxx.jar--server.port=9001
Java-jar Xxx.jar--server.port=9002
So you can run two apps and see the registration center.
And then call the next consumer log-instance.
As you can see, this time select the instance of Port 9002, and then refresh it:
This time you select another instance of Port 9001, indicating that load balancing does work.
At this point, a basic form of the SOA framework is set up, of course, there are many areas need to be improved, such as: How the registry to do Ha, service melts how to deal with, the registration center how to secure authentication (prevent other services disorderly registration), and so on, later.
Attached: example source code in the text Https://github.com/yjmyzz/spring-cloud-demo
Spring Cloud Learning (1)-Basic SOA example