Talking about SpringCloud's simple microservice architecture and springcloud
Spring Cloud is an ordered collection of a series of frameworks. With the convenience of Spring Boot, it cleverly simplifies the development of distributed system infrastructure, such as service discovery registration, configuration center, message bus, Server Load balancer, circuit breaker, and data monitoring, you can use the Spring Boot development style for one-click Start and deployment. Spring does not duplicate the manufacturing wheel. It just combines the mature and practical service frameworks developed by various companies, through the Spring Boot style re-encapsulation, the complex configuration and implementation principles are shielded, and finally a simple, easy-to-understand, easy-to-deploy and easy-to-maintain Distributed System Development Toolkit is provided for developers.
Next we will use SpringCloud to implement a simple microservice architecture.
All of the following code has been open source to github, address: https://github.com/lynnlovemin/softservice
Eureka (Service Registration and discovery)
First introduce the relevant dependent packages
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
Configure application. yml
server: port: 8761eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Create a startup Application
@EnableEurekaServer@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
Run the main method and access http: // localhost: 8761 in the browser. The following page is displayed in the browser:
This indicates that eureka is successfully started.
Next, we implement debt balancing, circuit breakers, gateways, and clients. All services should be registered in eureka, and all registered services can be seen by accessing eureka.
Client)
Pom. xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
Application. yml
Eureka: client: serviceUrl: defaultZone: http: // localhost: 8761/eureka/# Register server: port: 8763 spring: application: name: service-hi in eureka.
Application class
@ SpringBootApplication @ EnableEurekaClient @ RestControllerpublic class Application {public static void main (String [] args) {SpringApplication. run (Applicatioin. class, args) ;}@ Value ("$ {server. port} ") String port; // here we provide an interface @ RequestMapping ("/hi ") public String home (@ RequestParam String name) {return "hi" + name + ", I am from port:" + port ;}}
Feign (debt balancing, Circuit Breaker)
Pom. xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
Application. yml
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/server: port: 8765spring: application: name: service-feignfeign: hystrix: enabled: true
Application class
@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients@EnableHystrixDashboardpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
Then provide a service, which is used to balance liabilities and circuit breakers.
@FeignClient(value = "service-hi",fallback = SchedualServiceHiHystric.class)public interface SchedualServiceHi { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name);}
@Componentpublic class SchedualServiceHiHystric implements SchedualServiceHi { @Override public String sayHiFromClientOne(String name) { return "sorry "+name; }}
FeignClient: we specify the name: service-hi, fallback specified when the client was created, and the data returned when the service was unavailable, in this way, when multiple clients are started, we can see that different feign ports will be accessed alternately When http requests are made. When clien is stopped, an error message will be returned when the access interface is resumed.
Zuul (Service Gateway)
In general, we do not directly expose the client to the outside, but forward it through the Service Gateway. Internal Services communicate in the LAN, and external access fails, we can also perform interface security verification and intercept. Please refer to the Code:
Pom. xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository>
Application. yml
Eureka: client: serviceUrl: defaultZone: http: // localhost: 8761/eureka/server: port: 8080 spring: application: name: service-zuulzuul: routes: api-B: path:/api/** serviceId: service-feign # All requests starting with an api access the service-feign service.
Application class
@EnableZuulProxy@EnableEurekaClient@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
Start the Application and access http: // localhost: 8080/api/hi to access the previously defined interface. Next we will intercept the interface:
/*** FilterType: returns a string that represents the filter type. In zuul, four filter types with different lifecycles are defined, as follows: pre: routing before routing: post at route time: After route error: Send error call filterOrder: filter order shouldFilter: here we can write logic to determine whether to filter. This article is true, always filter. Run: The specific logic of the filter. The availability is complex, including querying SQL and nosql to determine whether the request has access permissions. * // @ Componentpublic class MyFilter extends ZuulFilter {private static Logger log = LoggerFactory. getLogger (MyFilter. class); @ Override public String filterType () {return "pre" ;}@ Override public int filterOrder () {return 0 ;}@ Override public boolean shouldFilter () {return true ;}@ Override public Object run () {RequestContext ctx = RequestContext. getCurrentContext (); HttpServletRequest request = ctx. getRequest (); log.info (String. format ("% s >>> % s", request. getMethod (), request. getRequestURL (). toString (); Object accessToken = request. getParameter ("token"); if (accessToken = null) {log. warn ("token is empty"); ctx. setSendZuulResponse (false); ctx. setResponseStatusCode (401); try {ctx. getResponse (). getWriter (). write ("token is empty");} catch (Exception e) {} return null;} log.info ("OK"); return null ;}}
In this way, we will first execute the run method in the MyFilter class before calling the interface. In this method, we can perform a series of security verification, such as token.
Well, a simple microservice architecture has been built.
All the above Code has been open source to github, address: https://github.com/lynnlovemin/softservice
The above is the simple microservice architecture of SpringCloud introduced by the small editor. I hope it will be helpful to you. If you have any questions, please leave a message and the small editor will reply in time.