

spring cloud vs kubernetes

-> jdk-11.0.15.1_windows-x64_bin.exe
-> spring-tool-suite-4-4.15.1.RELEASE-e4.24.0-win32.win32.x86_64.self-extracting.jar
-> apache-maven-3.8.6-bin.zip
jdk 11 설치
maven 압축해제
JAVA_HOME C:\Program Files\Java\jdk-11.0.15.1
Path %JAVA_HOME%\bin
MAVEN_HOME C:\apache-maven-3.8.6
Path %MAVEN_HOME%\bin
명령창 테스트
java -version
javac -version
mvn





캐시경로
C:\Users\HPE.m2\repository













https://projectlombok.org/download
java -jar lombok.jar을 STS에 설치

http://localhost:8080/v1/organization/optimaGrowth/license/2313202

eureka server







spring.application.name=MyServer
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8761




spring.application.name=MyClient1
server.port=8081
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true

package com.test.myclient1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class MyClient1Application {
 public static void main(String[] args) {
  SpringApplication.run(MyClient1Application.class, args);
 }
 @RequestMapping(value="/")
  public String hello() {
  return "Eureka Client Application";
 }
}



spring.application.name=MyClient2
server.port=8082
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true

spring.application.name=MyClient3
server.port=8083
eureka.instance.prefer-ip-address=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true

package com.test.myclient3;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.test.myclient3.MyClient3Application;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class MyClient3Application {
 public static void main(String[] args) {
 SpringApplication.run(MyClient3Application.class, args);
}
@RequestMapping(value="/")
public String hello() {
 return "Eureka Client Application #3";
}
}


마이크로서비스 기반 아키텍처(MSA) VS 서비스 지향 아키텍처(SOA)

server:
port: 9000
spring:
cloud:
gateway:
routes:
- id: helloModule
uri: http://localhost:8086/
predicates:
- Path=/hello/**
- id: goodbyeModule
uri: http://localhost:8087/
predicates:
- Path=/goodbye/**
http://localhost:9000/hello
-> http://localhost:8086/hello
http://localhost:9000/goodbye
-> http://localhost:8087/goodbye
Gateway Server http://localhost:9000/hello or goodbye
Service #1 http://localhost:8086
Service #1 http://localhost:8087
ApiGateway 9001 - gateway, eurekaclient
Loadbalancer 9000 - loadbalancer, eurekaclient
EurekaServer 8090 - eurekaserver
Service01 8081 - eurekaclient, spring mvc
Service02 8082 - eurekaclient, spring mvc




package com.test.model;
public class Member {
private String id;
private String name;
}



package com.test.model;
 public class Member {
  private String id;
  public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 private String name;
}


package com.test.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.model.Member;
@RestController
public class MemberController {
 @RequestMapping(value="/member", method=RequestMethod.GET)
 public Member getInfo() {
  Member m = new Member();
  m.setId("hong");
  m.setName("홍길동");
  return m;
 }
}
package com.test.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.model.Member;
@RestController
public class MemberController {
	@RequestMapping(value="/member", method=RequestMethod.GET)
	public Member getInfo() {
		Member m = new Member();
		m.setId("hong");
		m.setName("홍길동");
		return m;
	}
}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.test</groupId>
	<artifactId>Service01</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Service01</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
		<spring-cloud.version>2021.0.3</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</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-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</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>${spring-cloud.version}</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>
</project>






spring.application.name=EurekaServer
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8090


package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
}




spring.application.name=Service01
server.port=8081
eureka.client.service-url.defaultZone=http://localhost:8090/eureka



spring.application.name=EurekaServer
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8090
eureka.client.service-url.defaultZone=http://localhost:8090/eureka/
http://localhost:8080/member1
http://localhost:8080/member2
http://localhost:8090
http://localhost:8081/member
http://localhost:8082/member2






package com.test.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Controller;
@Controller
public class ConsumerControllerClient {
	@Autowired
	private LoadBalancerClient loadBalancer;
	public void getHello() {
		ServiceInstance serviceInstance = loadBalancer.choose("SERVICE");
		System.out.println(serviceInstance.getUri());
		String baseUrl = serviceInstance.getUri().toString();
		baseUrl = baseUrl = "/member";
		// http://localhost:9000/member
		// -> http://localhost:8081/member -> SERVICE01
		// -> http://loaclhost:8082/member -> SERVICE02
	}
}



package com.test.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.client.RestTemplate;
@Controller
public class ConsumerControllerClient {
	@Autowired
	private LoadBalancerClient loadBalancer;
	public void getHello() {
		ServiceInstance serviceInstance = loadBalancer.choose("SERVICE");
		System.out.println(serviceInstance.getUri());
		String baseUrl = serviceInstance.getUri().toString();
		baseUrl = baseUrl = "/member";
		// http://localhost:9000/member
		// -> http://localhost:8081/member -> SERVICE01
		// -> http://loaclhost:8082/member -> SERVICE02
		RestTemplate restTemplate = new RestTemplate();
	}
}
package com.test.controllers;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.client.RestTemplate;
@Controller
public class ConsumerControllerClient {
	@Autowired
	private LoadBalancerClient loadBalancer;
	public void getMember() {
		ServiceInstance serviceInstance = loadBalancer.choose("SERVICE");
		System.out.println(serviceInstance.getUri());
		String baseUrl = serviceInstance.getUri().toString();
		baseUrl = baseUrl = "/member";
		// http://localhost:9000/member
		// -> http://localhost:8081/member -> SERVICE01
		// -> http://loaclhost:8082/member -> SERVICE02
		RestTemplate restTemplate = new RestTemplate(); 
		ResponseEntity<String> response=null;
		try{
			response=restTemplate.exchange(baseUrl,  HttpMethod.GET, getHeaders(),String.class);
		} catch (Exception ex) {
			System.out.println(ex);
		}
		System.out.println(response.getBody());
	}
	private static HttpEntity<?> getHeaders() throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
		return new HttpEntity<>(headers);
	}
}
package com.test;
import java.io.IOException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ApplicationContext;
import org.springframework.web.client.RestClientException;
import com.test.controllers.ConsumerControllerClient;
@SpringBootApplication
public class LoadbalancerApplication {
	public static void main(String[] args) throws RestClientException, IOException {
		ApplicationContext ctx = SpringApplication.run(LoadbalancerApplication.class, args);
		
		ConsumerControllerClient consumerControllerClient=ctx.getBean(ConsumerControllerClient.class);
		System.out.println(consumerControllerClient);
		for(int inx = 0; inx <= 10; inx++) {
			consumerControllerClient.getMember();
		}
	}
}

Service
/member




spring.application.name=LoadBalancer1
server.port=9000
eureka.client.serviceUrl.defaultZone=http://localhost:8090/eureka
package com.test.controllers;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.client.RestTemplate;
@Controller
public class ConsumerControllerClient {
	@Autowired
	private LoadBalancerClient loadBalancer;
	public void getMember() {
		ServiceInstance serviceInstance = loadBalancer.choose("SERVICE");
		System.out.println(serviceInstance.getUri());
		String baseUrl = serviceInstance.getUri().toString();
		baseUrl = baseUrl = "/member";
		// http://localhost:9000/member
		// -> http://localhost:8081/member -> SERVICE01
		// -> http://loaclhost:8082/member -> SERVICE02
		RestTemplate restTemplate = new RestTemplate(); 
		ResponseEntity<String> response=null;
		try{
			response=restTemplate.exchange(baseUrl,  HttpMethod.GET, getHeaders(),String.class);
		} catch (Exception ex) {
			System.out.println(ex);
		}
		System.out.println(response.getBody());
	}
	private static HttpEntity<?> getHeaders() throws IOException {
		HttpHeaders headers = new HttpHeaders();
		headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
		return new HttpEntity<>(headers);
	}
}
package com.test;
import java.io.IOException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ApplicationContext;
import org.springframework.web.client.RestClientException;
import com.test.controllers.ConsumerControllerClient;
@SpringBootApplication
public class LoadbalancerApplication {
	public static void main(String[] args) throws RestClientException, IOException {
		ApplicationContext ctx = SpringApplication.run(LoadbalancerApplication.class, args);
		
		ConsumerControllerClient consumerControllerClient=ctx.getBean(ConsumerControllerClient.class);
		System.out.println(consumerControllerClient);
		for(int inx = 0; inx <= 10; inx++) {
			consumerControllerClient.getMember();
		}
	}
}


//EurekaServer 미사용 코드 쿠현
package com.test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import java.util.Arrays;
import java.util.List;
@SpringBootApplication
public class LoadBalancerClientApplication {
	public static void main(String[] args) {
//		SpringApplication.run(LoadBalancerClientApplication.class, args);
		
		ConfigurableApplicationContext ctx = new SpringApplicationBuilder(LoadBalancerClientApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
        WebClient loadBalancedClient = ctx.getBean(WebClient.Builder.class).build();
        for(int i = 1; i <= 10; i++) {
            String response =
                loadBalancedClient.get().uri("http://example-service/hello")
                    .retrieve().toEntity(String.class)
                    .block().getBody();
            System.out.println(response);
        }
    }
}
@Configuration
class DemoServerInstanceConfiguration {
    @Bean
    ServiceInstanceListSupplier serviceInstanceListSupplier() {
        return new DemoInstanceSupplier("example-service");
    }
}
@Configuration
@LoadBalancerClient(name = "example-service", configuration = DemoServerInstanceConfiguration.class)
class WebClientConfig {
    @LoadBalanced
    @Bean
    WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}
class DemoInstanceSupplier implements ServiceInstanceListSupplier {
    private final String serviceId;
    public DemoInstanceSupplier(String serviceId) {
        this.serviceId = serviceId;
    }
    @Override
    public String getServiceId() {
        return serviceId;
    }
    @Override
    public Flux<List<ServiceInstance>> get() {
        return Flux.just(Arrays
            .asList(new DefaultServiceInstance(serviceId + "1", serviceId, "localhost", 8082, false),
                    new DefaultServiceInstance(serviceId + "2", serviceId, "localhost", 8083, false)));
    }
}
EurekaServer and Ribbon



spring.application.name=Service04
server.port=8084
package com.test.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.model.Member;
@RestController
public class MemberController {
	@RequestMapping(value="/goodbye", method=RequestMethod.GET)
	public Member getInfo() {
		Member m = new Member();
		m.setId("lee");
		m.setName("이순신");
		return m;
	}
}



server:
  port: 9000
spring:
  cloud:
    gateway:
      routes:
      - id: helloModule
        uri: http://localhost:8083/
        predicates:
        - Path=/hello/**
      - id: goodbye
        uri: http://localhost:8084/
        predicates:
        - Path=/goodbye/** 


spring cloud config server github
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo




server:
 port: 8888
spring:
 cloud:
  config:
   server:
    git:
     uri: https://github.com/formin/MySpringClud.git




server:
 port: 8089
spring:
 application:
  name: MyConfigClient
 cloud:
  config:
   name: myconfig
   profile: test
 config:
  import:
   configserver:http://localhost:8888

package com.test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class MyConfigClient1Application {
	public static void main(String[] args) {
		SpringApplication.run(MyConfigClient1Application.class, args);
	}
	
	@Value("${message.text:default}")
	private String messageValue;
	
	@RequestMapping(value="/")
	public String getMessageValue() {
		return messageValue;
	}
}
java -jar jenkins.war





Microservice Patterns: With examples in Java
Practical Microservices: Event Sourcing and CQRS with Event-Driven Architectures
스프링 부트 및 스프링 클라우드가 있는 핸드온 마이크로서비스: 스프링 클라우드, 이스티오, 쿠버네티스를 사용하여 Java 마이크로서비스 구축 및 배포
Cloud Native Java: 스프링 부츠, 스프링 클라우드 및 클라우드 파운드리가 있는 탄력적인 시스템 설계