The first few articles mainly focus on the use of eureka in the registration center. Next, you can create a service provider to register with eureka.
See the demo source code: https://github.com/Ryan-Miao/spring-cloud-Edgware-demo/tree/master/provider-demo
To facilitate version control, the next projects are configured based on the parent configuration https://github.com/Ryan-Miao/spring-cloud-Edgware-demo.
Create a child moudle provider-demo
Create a child module with the project name provider-demo. Fill in springboot and springcloud dependencies
<dependencies> <!--springboot dependency start--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--springboot Dependency End--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <!--Tool class start--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> </dependency> <!--Tool class end--> </dependencies>
spring-boot-starter-web provides web capabilities, spring-boot-starter-actuator provides project statistics and basic monitoring endpoint. If you want to use spring-boot-admin monitoring, you must add spring-boot-devtools development mode jackson-datatype-jsr310 can solve the new time of Java8 APILocalDate disintegration spring-cloud-starter-eureka eureka client, responsible for maintaining heartbeat and registering swagger provides Restful contract lombok It looks refreshing compilation level getter setter tool. guava 's large and complete Java essential class library logstash-logback-encoder wants to collect logs to ELK, use this appender
Startup class
@EnableDiscoveryClient@SpringBootApplicationpublic class ProviderDemoApplication { public static void main(String[] args) { SpringApplication.run(ProviderDemoApplication.class, args); }} @EnableDiscoveryClient to enable service registration
This ProviderDemoApplication should be placed at the outermost layer of the project package, because @SpringbootAppliatin contains the annotation of @ComponentScan, and the default scan is scanned under this class package, otherwise scan must be specified manually.
Swagger
Swagger is a configuration class
@EnableSwagger2@Configurationpublic class SwaggerConfiguration { private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Service Provider API") .description("Provide user information query") .termsOfServiceUrl("") .version("1.0.0") .build(); } /** * Define the api configuration. */ @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) .build() .apiInfo(apiInfo()); }}For the routing of the swagger page, we need to guide the following:
Create a controller to navigate
@Controllerpublic class HomeController { @GetMapping(value = {"/api", "/"}) public String api() { return "redirect:/swagger-ui.html"; }}Let's take a Controller interface
@Api@RestController@RequestMapping("/api/v1/users")public class UserController{ private List<User> users = Lists.newArrayList( new User(1, "Tan Haoqiang", 100, LocalDate.now()), new User(2, "Yan Weimin", 120, LocalDate.now()), new User(3, "Tan Haoqiang", 100, LocalDate.now()), new User(4, "James Gosling", 150, LocalDate.now()), new User(6, "Doug Lea", 150, LocalDate.now()) ); @GetMapping("/") public List<UserVo> list() { return users.stream() .map(u -> new UserVo(u.getId(), u.getName(), u.getAge(), u.getBirth())) .collect(Collectors.toList()); }}Some simple environment configurations
application.yml
spring: application: name: provider-demo jackson: serialization: WRITE_DATES_AS_TIMESTAMPS: false default-property-inclusion: non_null#Server expiration time configuration. If the heartbeat is not received after this time, EurekaServer will remove this instance. Note that EurekaServer must set eureka.server.eviction-interval-timer-in-ms, otherwise this configuration is invalid. This configuration is generally three times the service refresh time configuration. #Default 90seureka.instance.lease-expiration-duration-in-seconds: 15# service refreshes the time configuration, and the heartbeats will be active every time this time #Default 30seureka.instance.lease-renewal-interval-in-seconds: 5server: port: 8082springfox: documentation: swagger: v2: path: /swagger-resources/api-docslog: path: logs
application-dev.yml
management: security: enabled: falseseeureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/logstash: url: localhost:4560
I need to mention it here that since I integrate logstash, I must install logstash, see ELK for the introduction. Of course you can skip it, as long as you do not provide the logback.xml configuration, you can remove the logstash in the dependency.
Log configuration
Logback is used as the log framework by default. The simple configuration is as follows. For those who do not want to use logstash, just remove the logstash appender.
Create a new logback-spring.xml under resource
<?xml version="1.0" encoding="UTF-8"?><configuration scan="true" scanPeriod="60 seconds" debug="false"> <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="unknown"/> <springProperty scope="context" name="log.path" source="log.path" defaultValue="logs"/> <springProperty scope="context" name="logstashurl" source="logstash.url" defaultValue="localhost:4560"/> <include resource="org/springframework/boot/logging/logback/base.xml"/> <!--Output to console--> <appender name="console">LoggingInterceptor <encoder> <pattern>%d{HH:mm:ss.SSS} %X{req.remoteHost} %X{req.requestURI} ${appName} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <!--Output to file--> <appender name="file"> <rollingPolicy> <fileNamePattern>${log.path}/${appName}.%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <encoder> <pattern>%d{HH:mm:ss.SSS} ${appName} %X{req.remoteHost} %X{req.requestURI} %X{req.userAgent} %X{req.method} - [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <!-- Output to logstash--> <appender name="LOGSTASH"> <destination>${logstashurl}</destination> <encoder charset="UTF-8"/> </appender> <springProfile name="dev"> <root level="info"> <appender-ref ref="console"/> <appender-ref ref="file"/> <appender-ref ref="file"/> <appender-ref ref="file"/> <appender-ref ref="LOGSTASH"/> </root> </springProfile> <springProfile name="test, prod"> <root level="info"> <appender-ref ref="file"/> <appender-ref ref="LOGSTASH"/> </root> </springProfile></configuration>start up
Make sure that eureka has been started, admin is best to start, so as to facilitate viewing the app status, and ELK's logging system is also best available. Of course, only eureka is a necessity.
Compile and package
mvn clean install package spring-boot:repackage
Run the main method, specify the profile as dev, you can edit the run configuration in idea and add parameters
--spring.profiles.active=dev
Or start the command line jar
Copy the code as follows: java -Xms256m -Xmx1g -XX:+UseG1GC -jar ./target/provider-demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
After startup, access eureka
Visit admin
Visit provider-demo
Expose our API to the consumer
Since there are service providers, it must be for consumer consumption. How should consumers be consumed? Just call this http request manually. The swagger Restful contract mentioned earlier is the parameters and requirements provided by the service provider to request access. If the consumer develops this client manually, it will be time-consuming and error-prone. Therefore, as a service provider, you should provide SDK or client to the consumer for use.
In the spring cloud technology system, remote calls are naturally the top priority. The specific usage I have found is Feign+Ribbon+Hystrix.
Through Feign's declarative interface docking, the consumer calls to the provider is implemented. Ribbon client load balancing, hystrix is healthy circuit breaker.
Here, we first need to provide Feign's interface.
Refine the controller's api into an interface. First, we create a new project
https://github.com/Ryan-Miao/spring-cloud-Edgware-demo/tree/master/provider-api
Put this project in the dependency list of provider-demo
<!--Internal dependency--><dependency> <groupId>com.test</groupId> <artifactId>provider-api</artifactId> <version>0.0.1-SNAPSHOT</version></dependent><!--Internal dependency end-->
Exit the UserApi interface channel in the provider-api project
@RequestMapping("/api/v1/users")public interface UserApi { @GetMapping("/") List<UserVo> list();}The controller of provider-demo is modified as follows
@Api@RestControllerpublic class UserController implements UserApi { private List<User> users = Lists.newArrayList( new User(1, "Tan Haoqiang", 100, LocalDate.now()), new User(2, "Yan Weimin", 120, LocalDate.now()), new User(3, "Tan Haoqiang", 100, LocalDate.now()), new User(4, "James Gosling", 150, LocalDate.now()), new User(6, "Doug Lea", 150, LocalDate.now()) ); @Override public List<UserVo> list() { return users.stream() .map(u -> new UserVo(u.getId(), u.getName(), u.getAge(), u.getBirth())) .collect(Collectors.toList()); }}In this way, the controller has not changed, but has been pulled from the API path. The independent module provider-api is the client we provide to the consumer. The next section uses consumer to consume.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.