This is the 25th day of my participation in the August Genwen Challenge.More challenges in August
🌈 Past review
Thank you for reading, I hope to help you, if there is a flaw in the blog, please leave a message in the comment area or add my private chat in the home page, thank you for every little partner generous advice. I’m XiaoLin, a boy who can both write bugs and sing rap
- 1️ retail (suggested collection)
- 💖10 minutes to RocketMQ! You can’t even get into Ali? 2 ️ ⃣ 💖
- 💖10 minutes to RocketMQ! You can’t even get into Ali? 1 ️ ⃣ 💖
Second, the Spring Cloud
2.1. What is SpringCloud
SpringCloud is a development tool set containing many sub-projects and a collection of numerous open source frameworks. It makes use of the convenience of Spring Boot development to realize many functions, such as service registration, service registration discovery, load balancing, etc. In the process of integration, SpringCloud is mainly the encapsulation of open source components for Netflix. The advent of SpringCloud really simplifies distributed architecture development.
NetFlix is an online video website in the United States and a leader in micro-services. It is recognized as an outstanding practitioner of mass production-level micro-services. The open source components of NetFlix have been verified in its large-scale distributed micro-services environment for many years, so Spring Many components in the Cloud are packaged based on NetFlix components.
2.2. Core Components
- Eurekaserver, Consul, NACOS: Service registry components.
- Rabbion & OpenFeign: Service load balancing and service invocation components.
- Hystrix & Hystrix Dashboard: Service circuit breaker and Service monitoring component.
- Zuul, gateway: service gateway components.
- Config: Configures central components in a unified manner.
- Bus: Message bus component.
2.3 Version naming
SpringCloud is a large, integrated project made up of many independent sub-projects, each with a different release rhythm and maintaining its own release number. In order to better manage the release of SpringCloud, a resource list BOM(Bill of Materials) is used to avoid confusion with the release number of subprojects, so the version number is not used, but by naming. The names are arranged in alphabetical order. For example, the names of London Underground stations (” Angel “is the first version,” Brixton” is the second, and “Camden” is the third). When the point releases of individual projects accumulate to a critical mass, or there is a critical defect in one project that needs to be available to everyone, the release sequence will push out “service releases” with names ending in “.srx “, where “X” is a number.
The names of London Underground stations are roughly as follows: Angel, Brixton, Camden, Dalston, Edgware, Finchley, Greenwich, Hoxton.
2.4. Version selection
Because the SpringCloud version must match the SpringBoot version, you must select the SpringBoot version based on the SpringCloud version.
Third, SpringCloud Alibaba
3.1, introduction to
Spring Cloud Alibaba is a sub-project of Spring Cloud, which provides a one-stop solution for distributed application development with all the components needed to develop distributed applications. Allows you to easily develop applications using Spring Cloud. With Spring Cloud Alibaba, you can connect Spring Cloud applications to Alibaba’s distributed solution with just a few annotations and a little configuration. And use Alibaba middleware to build distributed application system. Spring Cloud Alibaba is the integration of Alibaba open source middleware and Spring Cloud system.
3.2 main functions
- Traffic control and service degradation: Default support for WebServlet, WebFlux, OpenFeign, RestTemplate, Spring Cloud, Gateway, Zuul, Dubbo and RocketMQ traffic limiting degrade function access, You can modify traffic limiting degradation rules in real time through the console at runtime and view the Metrics of traffic limiting degradation.
- Service registration and discovery: Instances can be registered on Alibaba Nacos, customers can discover instances using Spring-managed beans, and Ribbon client load balancer is supported through Spring Cloud Netflix.
- Distributed configuration management: Supports external configuration in distributed systems, and automatically refreshes configuration changes.
- Message driven capabilities: Build message driven capabilities for microservice applications based on Spring Cloud Stream.
- Message Bus: Use Spring Cloud Bus RocketMQ to link nodes of a distributed system.
- Distributed Transactions: Solve distributed transaction problems efficiently and without intrusion to the business using the @GlobalTransactional annotation.
- Dubbo RPC: The communication protocol that extends Spring Cloud services to service invocations via Apache Dubbo RPC.
- Distributed task scheduling: provides second-level, precise, highly reliable, and highly available scheduled (Cron expression based) task scheduling services. It also provides a distributed task execution model, such as grid tasks. Grid tasks allow quantum tasks to be evenly distributed to all workers (schedulerx-client) for execution.
3.3, components,
- Sentinel: Take traffic as the entry point to protect the stability of services from multiple dimensions, such as flow control, fuse downgrading and system load protection.
- Nacos: A dynamic service discovery, configuration management, and service management platform that makes it easier to build cloud-native applications.
- RocketMQ: An open source distributed messaging system that provides low-latency, highly reliable message publishing and subscription services based on highly available distributed clustering technology.
- Dubbo: Apache Dubbo™ is a high-performance Java RPC framework.
- Seata: Alibaba open source product, an easy-to-use high-performance microservices distributed transaction solution.
- Alibaba Cloud ACM: an application configuration center that centrally manages and pushes application configurations in a distributed architecture environment.
- Alibaba Cloud OSS: Alibaba Cloud Object Storage Service (OSS) is a massive, secure, low-cost and highly reliable Cloud Storage Service provided by Alibaba Cloud. You can store and access any type of data in any application, anytime, anywhere.
- Alibaba Cloud SchedulerX: a distributed task scheduling product developed by Alibaba Middleware team, which provides second-level, accurate, highly reliable and highly available timed (Cron expression based) task scheduling service.
- Alibaba Cloud SMS: global SMS service, friendly, efficient and intelligent interconnected communication capabilities, to help enterprises quickly build customer access channels.
Iv. Micro-service project construction
4.1. Technology selection
- Persistence layer: SpingData Jpa
- Database: MySQL5.7
- Technology stack: SpringCloud Alibaba Technology stack
4.2 Module design
We built a microservice project, but only simple code, no business logic.
- Shop – the parent the parent project
- Shop-product-api: Product microservice API for storing product entities.
- Shop-product-server: product microservice, its 1 port is 808x.
- Shop-order-api Order microservice API, used to store order entities.
- Shop-order-server order micro service, its port is 808X.
4.3 Invocation of microservices
; In microservices architecture, the most common scenario is that microservices call each other. We take the common user order in the e-commerce system as an example to demonstrate the invocation of microservice: the customer initiates an order request to the order microservice, and before saving the order, the product microservice needs to be called to query the information of the product.
We generally call the active invokers of services as service consumers, and the invoked parties of services as service providers.
4.4. Create a parent project
Create a Maven project and add the following to the POM.xml file
<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 http://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.3.3. RELEASE</version>
<relativePath/>
</parent>
<groupId>cn.linstudy</groupId>
<artifactId>Shop-parent</artifactId>
<packaging>pom</packaging>
<version>1.0.0</version>
<modules>
<module>Shop-order-api</module>
<module>Shop-order-server</module>
<module>Shop-product-api</module>
<module>Shop-product-server</module>
</modules>
<properties>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.3. RELEASE</spring-cloud-alibaba.version>
</properties>
<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>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Copy the code
4.5. Create goods and services
4.5.1 Write the dependency of shop-product-API
Create the shop-product-API project and add the following to the POM.xml file
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Shop-parent</artifactId>
<groupId>cn.linstudy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Shop-product-api</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
4.5.2 Creating entities
/ / goods
@Entity(name = "t_shop_product")
@Data
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long pid;/ / the primary key
private String pname;// Product name
private Double pprice;// Commodity prices
private Integer stock;/ / inventory
}
Copy the code
4.5.3 Write the dependency of shop-product-server
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Shop-parent</artifactId>
<groupId>cn.linstudy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Shop-order-server</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<dependency>
<groupId>cn.linstudy</groupId>
<artifactId>Shop-order-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>cn.linstudy</groupId>
<artifactId>Shop-product-api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
Copy the code
4.5.4. Write Application.yml
server:
port: 8081
spring:
application:
name: product-service
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///shop-product? serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: admin
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Copy the code
4.5.5 Creating a database
Since we are using JPA, we need to create the database, but we do not need to create the table, because JPA automatically creates the table in the corresponding database.
4.5.6. Create DAO interfaces
// The first argument is the entity class, and the second argument is the primary key type of the entity class object
public interface ProductDao extends JpaRepository<Product.Long> {}Copy the code
4.5.7 Create the Service interface and its implementation class
public interface ProductService {
Product findById(Long productId);
}
Copy the code
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
ProductDao productDao;
@Override
public Product findById(Long productId) {
returnproductDao.findById(productId).get(); }}Copy the code
4.5.8 write Controller
@RestController
@Slf4j
public class ProductController {
@Autowired
private ProductService productService;
// Product information query
@RequestMapping("/product")
public Product findByPid(@RequestParam("pid") Long pid) {
Product product = productService.findByPid(pid);
returnproduct; }}Copy the code
4.5.9 Add test data
When we start the project, we can find that the table has been created automatically for us by default, and we need to import the test data.
INSERT INTO t_shop_product VALUE(NULL.'millet'.'1000'.'5000');
INSERT INTO t_shop_product VALUE(NULL.'huawei'.'2000'.'5000');
INSERT INTO t_shop_product VALUE(NULL.'apple'.'3000'.'5000');
INSERT INTO t_shop_product VALUE(NULL.'OPPO'.'4000'.'5000');
Copy the code
4.5.10, test,
4.6. Create order microservice
4.6.1 Write shop-order-API dependencies
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Shop-parent</artifactId>
<groupId>cn.linstudy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Shop-order-api</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
4.6.2 Create order entities
/ / order
@Entity(name = "t_shop_order")
@Data
@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
public class Order implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long oid;/ / order id
/ / user
private Long uid;/ / user id
private String username;/ / user name
/ / goods
private Long pid;Id / / commodities
private String pname;// Product name
private Double pprice;// Unit price
/ / the number of
private Integer number;// Purchase quantity
}
Copy the code
4.6.3 Create shop-order-server project
Add dependencies in pom.xml.
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Shop-parent</artifactId>
<groupId>cn.linstudy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Shop-order-server</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<dependency>
<groupId>cn.linstudy</groupId>
<artifactId>Shop-order-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>cn.linstudy</groupId>
<artifactId>Shop-product-api</artifactId>
<version>1.0.0</version>
</dependency>
</project>
Copy the code
4.6.4. Write Application.yml
server:
port: 8082
spring:
application:
name: order-service
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///shop-product? serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 1101121833
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Copy the code
4.6.5. Write Service and its implementation class
The Service interface and its implementation class we wrote do not have any business logic and are only used for testing purposes.
public interface OrderService {
Order getById(Long oid,Long pid);
}
Copy the code
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
OrderDao orderDao;
@Override
public Order getById(Long oid, Long pid) {
returnorderDao.getOne(oid); }}Copy the code
4.6.6. Creating a Controller
@RestController
@Slf4j
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping("getById")
public Order getById(Long oid,Long pid){
return orderService.getById(oid, pid);
}
Copy the code
4.7 how do services call each other
Suppose we need to call the commodity service in the order service, first query the commodity with ID 1, and then query its order, this 1 time involves the call between services. A 1 call between services is essentially an Http request made through Java code, and we can use the RestTemplate to make the call.
4.7.1 Add annotations to the shop-order-server startup class
Since we need the RestTemplate class, we need to inject the RestTemplate class into the container.
@SpringBootApplication
public class OrderServer {
public static void main(String[] args) {
SpringApplication.run(OrderServer.class,args);
}
@Bean
public RestTemplate restTemplate(a){
return newRestTemplate(); }}Copy the code
4.7.2 Modify the Controller code
@RestController
public class OrderController {
@Autowired
RestTemplate restTemplate;
@Autowired
OrderService orderService;
@RequestMapping("getById")
public Order getById(Long oid,Long pid){
Product product = restTemplate.getForObject(
"http://localhost:8083/product? productId="+pid,Product.class); / / here to launch through restTemplate HTTP request, the request address is http://localhost:8083/product, carrying parameter is productId
Order order = orderService.getById(oid, product.getPid());
order.setUsername(product.getPname());
returnorder; }}Copy the code
This completes the call between services.
4.8. Existing problems
Although we can already implement calls between microservices. However, we hardcoded the service provider’s network address (IP, port) into the code, which has many problems:
-
As soon as the service provider address changes, you need to manually modify the code.
-
Once there are multiple service providers, load balancing cannot be implemented.
-
Once services become more numerous, it is difficult to maintain the call relationships manually.
So how to solve it? This is where service governance needs to be implemented dynamically through a registry.