Spring Cloud Learning (1)-Basic SOA example

Source: Internet
Author: User
Tags zookeeper aliyun

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.