1 Nacos簡介
1.1 為什么叫Nacos?
- 前四個字母為Naming和Configuration的前兩個字母,最后的s為Service。
1.2 Nacos是什么?
- 是一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平台。
- Nacos:Dynamic Naming and Configuration Service。
- Nacos就是注冊中心和配置中心的結合,換言之Nacos=Eureka+Config+Bus。
1.3 Nacos能干嘛?
- 替代Eureka做服務注冊中心。
- 替代Config做服務配置中心。
1.4 去哪里下?
1.5 各種注冊中心比較
服務注冊和發現 | CAP模型 | 控制台管理 | 社區活躍度 |
---|---|---|---|
Eureka | AP | 支持 | 低(2.x版本閉源) |
Zookeeper | CP | 不支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP | 支持 | 高 |
據說Nacos在阿里內部有超過10萬的實例運行,已經過了類似雙十一等各種大型流量的考研。
2 安裝和運行
2.1 安裝
2.1.1 准備工作
- 本地安裝有JDK8和Maven3.x環境。
2.1.2 下載
- 下載地址。
2.2 運行
- 解壓縮安裝包。
- 直接在bin目錄下,使用
startup.cmd -m standalone
命令啟動Nacos。
- 命令運行成功后直接訪問http://localhost:8848/nacos(默認用戶名和密碼為nacos/nacos)。
- 登錄成功,結果頁面:
3 Nacos作為服務注冊中心
3.1 基於Nacos的服務提供者
3.1.1 新建Module,並導入相關依賴
- 父工程pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 本模塊pom修改部分:
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 本模塊pom完整部分:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud_alibaba_provider9013</artifactId>
<dependencies>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-actuator</artifactId>
</dependency>
</dependencies>
</project>
3.1.2 修改配置文件
- application.yml
server:
port: 9013
spring:
application:
name: cloud-alibaba-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 配置Nacos的地址
management:
endpoints:
web:
exposure:
include: '*'
3.1.3 啟動類
package com.sunxiaping.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author 許大仙
* @version 1.0
* @since 2020-10-11 10:54
*/
@SpringBootApplication
@EnableDiscoveryClient
public class CloudAlibabaProvider9013Application {
public static void main(String[] args) {
SpringApplication.run(CloudAlibabaProvider9013Application.class, args);
}
}
3.1.4 業務邏輯
- PaymentController.java
package com.sunxiaping.alibaba.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 許大仙
* @version 1.0
* @since 2020-10-11 10:57
*/
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/{id}")
public String payment(@PathVariable(value = "id") Integer id) {
return "Nacos的注冊中心的端口是:" + serverPort + ",id是:" + id;
}
}
3.2 基於Nacos的服務消費者
3.2.1 新建Module,並導入相關依賴
- 父工程pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 修改部分:
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 完整部分:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud_alibaba_provider9015</artifactId>
<dependencies>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-actuator</artifactId>
</dependency>
</dependencies>
</project>
3.2.2 修改配置文件
- application.yml
server:
port: 9015
spring:
application:
name: cloud-alibaba-consumer
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 配置Nacos的地址
management:
endpoints:
web:
exposure:
include: '*'
3.2.3 啟動類
package com.sunxiaping.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author 許大仙
* @version 1.0
* @since 2020-10-11 11:34
*/
@SpringBootApplication
@EnableDiscoveryClient
public class CloudAlibabaConsumer9015Application {
public static void main(String[] args) {
SpringApplication.run(CloudAlibabaConsumer9015Application.class, args);
}
}
3.2.4 業務邏輯
- SpringConfig.java
package com.sunxiaping.alibaba.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author 許大仙
* @version 1.0
* @since 2020-10-11 11:35
*/
@Configuration
public class SpringConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- OrderController.java
package com.sunxiaping.alibaba.controller;
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;
import org.springframework.web.client.RestTemplate;
/**
* @author 許大仙
* @version 1.0
* @since 2020-10-11 11:35
*/
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/order/{id}")
public String order(@PathVariable(value = "id") Integer id) {
return restTemplate.getForObject("http://cloud-alibaba-provider" + "/payment/" + id, String.class);
}
}
4 各種服務注冊中心對比
4.1 Nacos生態圖
4.2 Nacos服務發現實例模型
4.3 Nacos和其他注冊中心特性對比
4.4 Nacos支持AP和CP模式的切換
4.4.1 概述
- 如果不需要存儲服務級別的信息且服務實例是通過Nacos Client注冊,並能夠保持心跳上報,那么就可以選擇AP模式。當前主流的服務如Spring Cloud和Dubbo服務,都適用於AP模式,AP模式為了服務的可用性而減弱了一致性,因此AP模式下只支持臨時實例。
- 如果需要在服務級別編輯或者存儲配置信息,那么CP是必須,K8s服務和DNS服務則使用於CP模式。CP模式下支持注冊服務化實例,此時則是以Raft協議為集群運行模式,該模式下注冊實例之前必須先注冊服務,如果服務不存在,則會返回錯誤。
4.4.2 模式切換
- Nacos集群默認支持的CAP原則中的AP原則,但是也可以支持CP原則,切換命令如下:
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
- 同時微服務的bootstrap.properties需要配置如下選擇指明注冊為臨時/永久實例(AP模式不支持數據一致性,所以只支持服務注冊的臨時實例,CP模式支持服務注冊的永久實例)。
#false為永久實例,true表示臨時實例開啟,注冊為臨時實例
spring.cloud.nacos.discovery.ephemeral=false
5 Nacos作為服務配置中心的基礎配置
5.1 新建Modele,並導入相關依賴
- 修改部分:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 完整部分:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud_alibaba_config_server3377</artifactId>
<dependencies>
<!--nacos-config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--web + actuator-->
<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>
</dependencies>
</project>
5.2 YML
-
Nacos和Spring Cloud Config一樣,在項目初始化的時候,要保證先從配置中心進行配置拉取,拉取配置之后,才能保證項目的正常啟動。
-
SpringBoot中配置文件的加載時存在優先級順序的,bootstrap優先級高於application。
-
示例:
-
bootstrap.yml
spring:
application:
name: service-proudct
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 服務注冊中心的地址
config:
server-addr: 127.0.0.1:8848 # 配置中心的地址
file-extension: yml # 執行yaml格式的配置
management:
endpoints:
web:
exposure:
include: '*'
5.3 向Nacos中添加配置信息
-
Nacos中的dataId的組成格式和Spring Cloud中的配置文件的匹配規則。
-
官方地址。
5.4 啟動類
package com.sunxiaping;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
5.5 業務邏輯
- Product.java
package com.sunxiaping.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tb_product")
public class Product implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "product_name")
private String productName;
@Column(name = "status")
private Integer status;
@Column(name = "price")
private BigDecimal price;
@Column(name = "product_desc")
private String productDesc;
@Column(name = "caption")
private String caption;
@Column(name = "inventory")
private String inventory;
}
- ProductRepository.java
package com.sunxiaping.dao;
import com.sunxiaping.domain.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
}
- ProductService.java
package com.sunxiaping.service;
import com.sunxiaping.domain.Product;
public interface ProductService {
/**
* 根據id查詢
*
* @param id
* @return
*/
Product findById(Long id);
/**
* 保存
*
* @param product
*/
void save(Product product);
/**
* 更新
*
* @param product
*/
void update(Product product);
/**
* 刪除
*
* @param id
*/
void delete(Long id);
}
- ProductServiceImpl.java
package com.sunxiaping.service.impl;
import com.sunxiaping.dao.ProductRepository;
import com.sunxiaping.domain.Product;
import com.sunxiaping.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductRepository productRepository;
@Override
public Product findById(Long id) {
return this.productRepository.findById(id).orElse(new Product());
}
@Override
public void save(Product product) {
this.productRepository.save(product);
}
@Override
public void update(Product product) {
this.productRepository.save(product);
}
@Override
public void delete(Long id) {
this.productRepository.deleteById(id);
}
}
- ProductController.java
package com.sunxiaping.controller;
import com.sunxiaping.domain.Product;
import com.sunxiaping.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/product")
@RefreshScope //開啟動態刷新
public class ProductController {
@Value("${server.port}")
private String port;
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Autowired
private ProductService productService;
@PostMapping(value = "/save")
public String save(@RequestBody Product product) {
this.productService.save(product);
return "新增成功";
}
@GetMapping(value = "/findById/{id}")
public Product findById(@PathVariable(value = "id") Long id) {
Product product = this.productService.findById(id);
product.setProductName("訪問的地址是:" + this.ip + ":" + this.port);
return product;
}
}
6 Nacos作為服務配置中心的分類配置
6.1 問題:多項目多環境問題
6.1.1 問題1
- 在實際開發中,通常一個系統會准備:dev開發環境,test測試環境,prod生產環境。如何保證指定環境啟動時服務能正確讀取到Nacos上相應環境的配置文件?
6.1.2 問題2
- 一個大型分布式微服務會有很多微服務子項目,每個微服務服務又都會有相應的開發環境、測試環境、預發布環境、正式環境等等,如果對這些微服務配置進行管理?
6.2 Nacos圖形化界面管理
6.2.1 配置列表
6.2.2 命名空間
6.3 Namespace+Group+DataId什么關系,為什么這么設計?
6.3.1 Namespace+Group+DataId是什么?
- Namespace+Group+DataId類似於Java里面的package(包名)和類名。
- 最外層的namespace是可以用於區分部署環境的,Group和DataId邏輯上區分兩個目標對象。
6.3.2 Namespace+Group+DataId的關系以及設計的意圖
- 默認情況下,Namespace=public、Group=DEFAULT_GROUP,默認Cluster是DEFAULT。
- Nacos的默認的命名空間是public,Namespace主要用來實現隔離。比如說,現在有三個環境:開發、測試和生產環境,我們就可以創建三個Namespace,不同的Namespace之間是隔離的。
- Group默認是DEFAULT_GROUP,Group可以把不同的微服務划分到同一個分組里面。
- Service就是微服務。一個Service可以包含多個Cluster(集群),Nacos默認Cluster就是DEFAULT,Cluster是對指定微服務的一個虛擬划分。比如說,為了容災,將Service微服務分別部署在了杭州機房和廣州機房,這時候就可以給杭州機房的Service微服務起一個集群名稱(HZ),給廣州機房的Service微服務起一個集群名稱(GZ),還可以盡量讓同一個機房的微服務互相調用,以提升性能。
- Instance,就是微服務的實例。
7 Nacos集群和持久化配置
7.1 官網說明
7.1.1 官網地址
- 官網地址。
7.1.2 官網集群架構圖
7.1.3 Nacos集群架構圖理解
7.1.4 說明
7.2 單機版的Nacos持久化配置
-
Nacos默認自帶的是嵌入式數據庫derby,不方便觀察數據存儲的基本情況,需要將數據源由derby切換到MySQL。
-
derby切換到MySQL的步驟:
-
1️⃣安裝MySQL數據庫,版本要求5.6.5+。
-
2️⃣初始化MySQL數據庫,數據庫的sql腳本在nacos/conf/nacos-mysql.sql文件中:
- 3️⃣修改conf/application.properites文件,增加支持MySQL數據源配置(目前只支持MySQL),添加MySQL的數據源的URL、用戶和密碼等。
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
7.3 Linux版Nacos+MySQL生產環境配置
7.3.1 准備工作
- Nginx:1個。
- Nacos Server:3個。
- MySQL:1個(IP地址為192.168.32.100,端口是3306)。
- Centos7:3個(IP地址分別為192.168.32.100、192.168.32.101和192.168.32.102)。
7.3.2 邏輯架構圖
7.3.3 在每個Centos7系統中下載Linux版本的Nacos
cd /opt
wget https://github.91chifun.workers.dev//https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-server-1.3.2.tar.gz
tar -zxvf nacos-server-1.3.2.tar.gz
7.3.4 將nacos-mysql.sql文件導入到MySQL數據庫中
7.3.4 持久化配置
- 在每個CentOS7系統上的Nacos的conf/application.properties文件中加入如下的配置:
# 在最后一行添加
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.32.100:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
7.3.5 集群配置
- 在每個CentOS7系統上的Nacos的conf目錄,復制cluster.conf.example文件,並改名為cluster.conf:
cp cluster.conf.example cluster.conf
- 修改每個CentOS7系統上的Nacos的conf/cluster.conf文件,並添加如下的配置:
192.168.32.100:8848
192.168.32.101:8848
192.168.32.102:8848
- 分別啟動各個Nacos服務。
/opt/nacos/bin
./startup.sh
7.3.6 修改Nginx的配置文件並啟動Nginx
- nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# -----------修改-----------------
upstream nacos {
server 192.168.32.100:8848;
server 192.168.32.101:8848;
server 192.168.32.103:8848;
}
# -----------修改-----------------
server {
# -----------修改-----------------
listen 8089;
# -----------修改-----------------
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
# -----------修改-----------------
location ^~ /nacos{
proxy_pass http://nacos;
# nginx非80端口處理
proxy_set_header Host $host:$server_port;
# 獲取真實IP
proxy_set_header X-Real-IP $remote_addr;
# 獲取代理者的真實ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 解決getScheme,isSecure,sendRedirect
proxy_set_header X-Forwarded-Scheme $scheme;
client_max_body_size 1000m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
# -----------修改-----------------
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}